为什么状态值不能反映在ReactJS中?

时间:2019-06-19 10:43:43

标签: javascript reactjs

class App extends Component {
  state = {
    name: ""
  };
  abc() {
    console.log("ddd");
    this.setState({
      name: "asd"
    });
  }
  render() {
    return <div>ddd{this.state.name}</div>;
  }
}

this.state.name没有体现。 https://codesandbox.io/s/vigorous-sky-woxr7

我从外面调用此函数。

我想从外部调用组件函数并更新状态。

6 个答案:

答案 0 :(得分:0)

那不是您编写React代码的方式。您应该执行以下操作:

import React, { Component } from 'react';

class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      name: ""
    }
  }

  setName = _ => {
    this.setState({ name: 'John Doe' })
  }

  render() {
    return (
      <>
        <div>
          {`This is my name: ${this.state.name}`}
        </div>
        <button onClick={this.setName}>Click me to see my name!</button>
      </>
    );
  }
}

export default App;

要考虑的两个重要关键:

  1. 状态必须在构造函数中初始化
  2. 您必须具有特定的功能来更新您可以从任何地方调用的状态。如果要在生命周期开始时启动它,请使用componentDidWount()方法。

  

更新:如果要从该组件外部调用

在这种情况下,您将有两个不同的组件,如果要从子组件中调用一个方法,则应执行以下操作:

父组件

import React, { Component } from 'react';
import MyComponent from './MyComponent'

class App extends Component {
   onClick = () => {
    this.myComponent.method()
  }
  render() {
    return (
      <div>
        <MyComponent onRef={ref => (this.myComponent = ref)} />
        <button onClick={this.onClick}>MyComponent.method()</button>
      </div>
    );
  }
}

export default App;

子组件

import React, { Component } from 'react';

class MyComponent extends Component {
  componentDidMount() {
    this.props.onRef(this)
  }
  componentWillUnmount() {
    this.props.onRef(undefined)
  }
  method() {
    window.alert('Hello there, my name is John Doe!')
  }
  render() {
    return <h1>Example of how to call a method from another component</h1>
  }
}

export default MyComponent;

在这里查看一个实时示例:https://repl.it/repls/AfraidNecessaryMedia

答案 1 :(得分:0)

我建议您在类内部调用类方法,但是如果您想解决问题,请在index.js上使用React.createRef()

const rootElement = document.getElementById("root");
const ref = React.createRef();
ReactDOM.render(<App ref={ref} />, rootElement);
ref.current.abc();

https://codesandbox.io/embed/sleepy-glitter-fwplz

import React, { Component } from "react";
import ReactDOM from "react-dom";

import "./styles.css";
window.a = function() {
  ref.current.abc();
};

class App extends Component {
  state = {
    name: ""
  };
  abc() {
    console.log("ddd");
    this.setState({
      name: "asd"
    });
  }
  render() {
    return <div>ddd{this.state.name}</div>;
  }
}

const rootElement = document.getElementById("root");
const ref = React.createRef();
ReactDOM.render(<App ref={ref} />, rootElement);
window.a();

答案 2 :(得分:0)

怎么样?

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: ""
    };
  }

  componentDidMount() {
    this.abc();
  }

  abc() {
    console.log("ddd");
    this.setState({
      name: "asd"
    });
  }

  render() {
    return <div>ddd {this.state.name}</div>;
  }
}

答案 3 :(得分:0)

调用该函数的方式不正确。
记住:需要调用一个函数...
对于第二个问题:您不能从子级调用函数到父级。
在这种情况下,您应该在父级中创建一个功能,发送给子级,然后在事件(组件加载,单击等)上调用它。
如果您确实需要这样做:将数据,函数和更多内容从子级发送到父级...请检查Redux https://redux.js.org/

这是您的代码在起作用(功能abc上的更改很小):

import React, { Component, Fragment } from "react"
import ReactDOM from "react-dom"    
import "./styles.css"

window.a = function() {
  var ab = new App()
  ab.abc()
}

class App extends Component {

state = {
    name: ""
  }

  abc = () => {
    this.setState({ name: "new name" })
  }

  render() {
    return (
      <Fragment>
        <div>{this.state.name}</div>
        <button onClick={this.abc}>call function</button>
      </Fragment>
    );
  }
}

const rootElement = document.getElementById("root")
ReactDOM.render(<App />, rootElement)
window.a()

请注意,请使用“;”在每一行的最后,不是编写React js的正确方法。
最佳做法链接:https://americanexpress.io/clean-code-dirty-code/

答案 4 :(得分:0)

您需要做两件事...

  1. 在构造函数中将abc()绑定到this 或像我一样使用箭头函数,否则您将无法访问this.setState()
  2. 使用生命周期方法而不是使用ComponentDidMount()在React外部调用函数。

这是更新的代码:

import React, { Component } from "react";
import ReactDOM from "react-dom";

class App extends Component {
  state = {
    name: ""
  };
  abc = () => {
    console.log("ddd");
    this.setState({
      name: "asd"
    });
  };
  componentDidMount() {
    this.abc();
  }
  render() {
    return <div>ddd {this.state.name}</div>;
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

CodeSandbox中的演示

答案 5 :(得分:0)

由于abc()不受此限制,并且方法使用setState(该对象中的方法),因此您有两种选择,两个可以解决此问题:

1-将this绑定到构造函数中的方法

2-将您的功能实现为箭头功能,而不是默认功能

第一种方法:

class App extends Component {
  constructor(props){
      super(props);
      this.state = {
          name: '',
      }

      this.abc = this.abc.bind(this);
  }
  abc(){
    console.log("ddd");
    this.setState({
      name: "asd"
    });
  };
  componentDidMount() {
    this.abc();
  }
  render() {
    return <div>ddd {this.state.name}</div>;
  }
}


第二种方法:

class App extends Component {
  state = {
      name: '',
  }
  abc = () => {
    console.log("ddd");
    this.setState({
      name: "asd"
    });
  };
  componentDidMount() {
    this.abc();
  }
  render() {
    return <div>ddd {this.state.name}</div>;
  }
}