我的结构如下所示:

Component 1

 - |- Component 2


 - - |- Component 4


 - - -  |- Component 5

Component 3

组件3应该根据组件5的状态显示一些数据。

因为道具是不可变的,我不能简单地在组件1中保存它的状态并转发它,对吗?是的,我读过Redux,但我不想使用它。我希望只用react就能解决这个问题。我错了吗?


当前回答

父组件

 function Parent() {
        const [value, setValue] = React.useState("");

        function handleChange(newValue) {
          setValue(newValue);
        }

        // We pass a callback to Child
        return <Child value={value} onChange={handleChange} />;
    }

子组件

    function Child(props) {
         function handleChange(event) {
             // Here, we invoke the callback with the new value
             props.onChange(event.target.value);
         }
  
         return <input value={props.value} onChange={handleChange} />
    }

其他回答

我想感谢得到最多赞的回答,因为他给了我自己的问题的想法,基本上是用箭头函数和从子组件传递参数的变化:

 class Parent extends React.Component {
  constructor(props) {
    super(props)
    // without bind, replaced by arrow func below
  }

  handler = (val) => {
    this.setState({
      someVar: val
    })
  }

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

class Child extends React.Component {
  render() {
    return <Button onClick = {() => this.props.handler('the passing value')}/ >
  }
}

希望它能帮助到别人。

这是如何使用新的useState钩子。

方法-将状态改变器函数作为道具传递给子组件,并对该函数做任何你想做的事情:

import React, {useState} from 'react';

const ParentComponent = () => {
  const[state, setState]=useState('');
  
  return(
    <ChildComponent stateChanger={setState} />
  )
}


const ChildComponent = ({stateChanger, ...rest}) => {
  return(
    <button onClick={() => stateChanger('New data')}></button>
  )
}

只需通过props将父组件的setState函数传递给子组件。

function ParentComp() {
  const [searchValue, setSearchValue] = useState("");
  return <SearchBox setSearchValue={setSearchValue} searchValue={searchValue} />;
}

然后在子组件中:

function SearchBox({ searchValue, setSearchValue }) {
  return (
        <input
          id="search-post"
          type="text"
          value={searchValue}
          onChange={(e) => setSearchValue(e.target.value)}
          placeholder="Search Blogs ..."
        />
    )
}

处理子组件点击的第二个例子:

// We've below function and component in parent component
const clickHandler = (val) => {
  alert(`httpRequest sent. \nValue Received: ${val}`);
};

// JSX
<HttpRequest clickHandler={clickHandler} />

这就是你如何从父组件中获取函数,然后传递一个值并通过它触发clickHandler。

function HttpRequest({ clickHandler }) {
  const [content, setContent] = useState("initialState");

  return (
    <button onClick={() => clickHandler(content)}>
      Send Request
    </button>
  );
}

export default HttpRequest;

我找到了以下工作解决方案,将onClick函数参数从子组件传递给父组件:

传递方法()的版本

//ChildB component
class ChildB extends React.Component {

    render() {

        var handleToUpdate = this.props.handleToUpdate;
        return (<div><button onClick={() => handleToUpdate('someVar')}>
            Push me
          </button>
        </div>)
    }
}

//ParentA component
class ParentA extends React.Component {

    constructor(props) {
        super(props);
        var handleToUpdate = this.handleToUpdate.bind(this);
        var arg1 = '';
    }

    handleToUpdate(someArg){
        alert('We pass argument from Child to Parent: ' + someArg);
        this.setState({arg1:someArg});
    }

    render() {
        var handleToUpdate = this.handleToUpdate;

        return (<div>
                    <ChildB handleToUpdate = {handleToUpdate.bind(this)} /></div>)
    }
}

if(document.querySelector("#demo")){
    ReactDOM.render(
        <ParentA />,
        document.querySelector("#demo")
    );
}

看看JSFiddle

使用传递箭头函数的版本

//ChildB component
class ChildB extends React.Component {

    render() {

        var handleToUpdate = this.props.handleToUpdate;
        return (<div>
          <button onClick={() => handleToUpdate('someVar')}>
            Push me
          </button>
        </div>)
    }
}

//ParentA component
class ParentA extends React.Component {
    constructor(props) {
        super(props);
    }

    handleToUpdate = (someArg) => {
            alert('We pass argument from Child to Parent: ' + someArg);
    }

    render() {
        return (<div>
            <ChildB handleToUpdate = {this.handleToUpdate} /></div>)
    }
}

if(document.querySelector("#demo")){
    ReactDOM.render(
        <ParentA />,
        document.querySelector("#demo")
    );
}

看看JSFiddle

如果同样的场景不是到处都有,你可以使用React的上下文,特别是如果你不想引入状态管理库所引入的所有开销。另外,它更容易学习。但是要小心;你可能会过度使用它并开始编写糟糕的代码。基本上,你定义了一个Container组件(它将保存并为你保存这段状态),使得所有的组件都对从它的子组件(不一定是直接的子组件)写入/读取这段数据感兴趣。

背景信息-反应

你也可以使用一个普通的React来代替。

<Component5 onSomethingHappenedIn5={this.props.doSomethingAbout5} />

将doSomethingAbout5传递给组件1:

<Component1>
    <Component2 onSomethingHappenedIn5={somethingAbout5 => this.setState({somethingAbout5})}/>
    <Component5 propThatDependsOn5={this.state.somethingAbout5}/>
<Component1/>

如果这是一个常见问题,那么您应该开始考虑将应用程序的整个状态转移到其他地方。你有几个选择,最常见的是:

回来的 通量

基本上,不是在组件中管理应用程序状态,而是在发生更新状态的情况时发送命令。组件也从这个容器中提取状态,因此所有数据都是集中的。这并不意味着您不能再使用局部状态,但这是一个更高级的主题。