我如何从 ReactJs 中的另一个组件调用 setState

Den*_*zer 12 components setstate reactjs

我有两个反应组件,我想调用 setState 在一个组件中设置状态,但在另一个组件中调用。我怎么做?

Kor*_*exx 31

If you work with functional components you can use hooks like useState. Don't forget to "save" (memoize) the reference of your handler with useCallback, it helps React avoid useless rerenders.

Functional component solution

// myContainer.js
import React, { useState } from 'react'
import MyChild from 'some/path/myChild'

function MyContainer() {
  const [name, setName] = useState('foo')

  return (
    <MyChild name={name} onNameChange={setName} />
  )
}

export default MyContainer

// myChild.js
import React, { useCallback } from 'react'

function MyChild({ name, onNameChange }) {

  const handleInputChange = useCallback(event => {
    onNameChange(event.target.value)
  }, [onNameChange])

  return (
    <div>
      <input type="text" onChange={handleInputChange} value={name} />
      <div>The name is: {name}</div>
    </div>
  )
}

export default MyChild
Run Code Online (Sandbox Code Playgroud)

In a class you can use handler (method) that contains some logic or function call(s). It help to keep your code maintainable.

Class component solution

// myContainer.js
import React, { Component } from 'react'
import MyChild from 'some/path/myChild'

class MyContainer extends Component {
  state = {
    name: 'foo'
  }

  handleNameChange = name => {
    this.setState({ name })
  }

  render() {
    return (
      <MyChild name={this.state.name} onNameChange={this.handleNameChange} />
    )
  }

}

export default MyContainer

// myChild.js
import React, { Component } from 'react'

class MyChild extends Component {

  handleInputChange = event => {
    this.props.onNameChange(event.target.value)
  }

  render() {
    return (
      <div>
        <input type="text" onChange={this.handleInputChange} value={this.props.name} />
        <div>The name is: {this.props.name}</div>
      </div>
    )
  }

}

export default MyChild
Run Code Online (Sandbox Code Playgroud)

  • @SanjivPradhanang 也许您可以打开一个问题线程,用代码示例公开您的问题。这样会更容易提出解决方案。 (2认同)

Ada*_*dam 8

You can't directly call setState on a parent component from a child component because the updating of a component state is restricted to the current component.

To handle this, simply pass a function from the parent to the child that contains setState. So when you want to update the parent's state, just call that passed function.

A minimal example:

// Parent.jsx

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

class Parent extends Component {
  constructor(props) {
    super(props);
    this.setChanged = this.setChanged.bind(this);
    this.state = {
      changed: false
    }
  }

  // Function to set the parent's state
  setChanged() {
    this.setState({ changed: true });
  }

  render() {
    return <Child setChanged={this.setChanged} />
  }
}

// Child.js

import React from 'react';

function Child(props) {
  return (
    // When clicked, parent's setChanged function is called
    <div onClick={() => props.setChanged()} />
  )
}
Run Code Online (Sandbox Code Playgroud)

  • 类型错误:props.setChanged 不是函数 (3认同)