【问题标题】:setState doesn't work when function passed through props is used使用通过 props 传递的函数时 setState 不起作用
【发布时间】:2023-03-20 13:35:01
【问题描述】:

我有一个执行 ajax 请求(通过 axios)的 React 组件 (App.js)。通过这些请求传递的参数值取自用户操作的输入字段。根据响应,它会更新其状态。

sendValue(value) {
  const url = `${myURl}/c${value}\r`;
  axios.get(url)
        .then(res=>{
              this.setState({
                       data:res.data
              })
         })
         .catch(err => {
            console.log('err', err);
         })  
}

然后在return语句中,这个函数作为prop传递给子组件:

<Child sendValue={this.sendValue}>

子组件 (Child.js) 有几个输入字段。这个子组件有自己的状态。当输入字段发生变化时,值会通过 props 传递给 axios 函数。

handleChange(e) {
      const { value } = e.target;
      this.setState({ input: value }, console.log('state', this.state));
      this.props.sendValue(`${value}\r`);
}

实际的输入元素如下所示:

<input
    value={this.state.value}
    onChange={this.handleChange}
 />

如果我省略这行this.props.sendValue(${value}\r);,状态会更新并且输入字段的值会发生变化(作为回调函数的console.log 证明了这一点,并且输入字段的实际值也会发生变化)。 但是当我把它留在里面时,什么都没有改变,状态永远不会更新,console.log 永远不会被调用。

为什么?

我该如何解决这个问题?

【问题讨论】:

  • 您是否将 sendValue 绑定到它的定义位置?
  • 是的,我通过this.sendValue = this.sendValue.bind(this);在构造函数中绑定它
  • 开发工具控制台中的任何错误?
  • 你绑定handleChange了吗??
  • 我确实绑定了handleChange,并且在开发控制台中没有错误

标签: javascript reactjs state react-props


【解决方案1】:

我假设您的 Child 组件如下所示,问题出在 Child 的构造函数中,我猜您在那里初始化了状态。

class Child extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      value: 'init-value' // or null
    }

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
   ....
  }

  render() {
    return (
      ....
      <input value={this.state.value} onChange={this.handleChange} />
      ....
    );
  }
}

this.props.sendValue 是从(属于)父组件传递的函数,它包含setState 语句。如果它被触发,就会发生父组件重新渲染。

handleChange(e)函数中,在

之后

this.setState({ input: value }, console.log('state', this.state));

改变孩子的状态

this.props.sendValue(`${value}\r`);

重新渲染 Parent 组件,当然 Child 也参与其中。 于是state的值又被初始化了,好像什么都没发生。

也许您想使用父组件中的道具为state.value 赋予价值。

【讨论】:

  • 啊,好吧,我明白了。是的,这可行,但是我必须将所有内容的所有状态都放入父组件中,这使得父组件的状态非常大,尤其是在项目变得非常大的情况下。这是你应该做的吗?
  • @Tom,这都是关于设计模式的,如果您的 Parent 组件很胖但维护合理,我认为没关系。或者,直接进入 redux,它就是为此而生的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-29
  • 2010-11-16
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
  • 2018-06-20
  • 1970-01-01
相关资源
最近更新 更多