我们可以将 setState 作为 props 从一个组件传递到另一个组件并在 React 中从子组件更改父状态吗?

vis*_*ram 7 javascript function setstate reactjs react-props

 class App extends Component {
  constructor() {
    super();
    this.state = {
      name: 'React'
    };
    this.setState=this.setState.bind(this)
  }

  render() {
    return (
      <div>
        <Hello name={this.state.name} />
        <p>
          Start editing to see some magic happen :)
        </p>
        <Child {...this}/>
      </div>
    );
  }
}

child Component
var Child=(self)=>{
  return(
    <button  onClick={()=>{
      self .setState({
        name:"viswa"
      })
    }}>Click </button>
  )
Run Code Online (Sandbox Code Playgroud)

在这里我绑定 setState 函数并将其作为道具发送到子组件。这将改变父组件的状态。这是正确的方法吗?

欧阳维*_*阳维杰 11

您不应该直接传递 setState,因为 setState 函数不会立即更改状态。

正如文件所说:

将 setState() 视为更新组件的请求而不是立即命令。为了获得更好的感知性能,React 可能会延迟它,然后一次更新多个组件。React 不保证状态更改立即应用。

setState() 并不总是立即更新组件。它可能会批量更新或推迟更新。因此,您最好一起管理 setState 函数的调用,因为可能会发生竞争,改变父级的状态。不建议将此功能传递给其他组件。

将 setState 函数的调用封装在一个类中可以使您的代码更强大。


tri*_*ixn 9

但这比传递函数简单。如果我想改变很多状态改变。与传递函数相比,这将是简单快捷的方法,对吧?

正确的方法与您的方法一样简单,并且不违反最佳实践:

class App extends Component {
  state = {
      name: 'React',
  };

  render() {
    return (
      <div>
        <Hello name={this.state.name} />
        <p>
          Start editing to see some magic happen :)
        </p>
        <Child onClick={() => this.setState({name: 'viswa'})}/>
      </div>
    );
  }
}

const Child=({onClick})=>(
    <button onClick={onClick}>Click</button>
);
Run Code Online (Sandbox Code Playgroud)

  • @viswaram 通过将 `setState` 传递给孩子,您将暴露父级的内部。您的孩子必须知道状态是如何实现的,因此您不能重用子组件。这不是一个好的做法,并且与正确的方法相比没有任何优势。 (2认同)

Chr*_*ris 0

正如 @yBrodsky 所说,您应该传递一个确实会改变状态的函数。这是一个例子:

class App extends Component {
  constructor() {
    super();
    this.state = {
      name: 'React'
    };
    this.update=this.update.bind(this);
  }

  update(nextState) {
    this.setState(nextState);
  }

  render() {
    return (
      <Child updateParent={this.update} />
    );
  }
}

const Child = ({updateParent}) => (
  <button onClick={() => updateParent({name: 'Foo bar'})}>Click</button>
);
Run Code Online (Sandbox Code Playgroud)

您现在可以完全控制子级中父级的状态。只需传递要浅合并到父状态的对象即可。在此示例中,nameinApp将更改为Foo bar单击按钮时。