我的结构如下所示:

Component 1

 - |- Component 2


 - - |- Component 4


 - - -  |- Component 5

Component 3

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

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


当前回答

我们可以通过将一个函数作为props传递给子组件来设置子组件的父状态,如下所示:

class Parent extends React.Component{
    state = { term : ''}

     onInputChange = (event) => {
         this.setState({term: event.target.value});
     }

     onFormSubmit = (event) => {
         event.preventDefault();
         this.props.onFormSubmit(this.state.term);
     }

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


class Child extends React.Component{

     render(){
         return (
             <div className="search-bar ui segment">
                 <form className="ui form" onSubmit={this.props.onFormSubmit}>
                     <div class="field">
                         <label>Search Video</label>
                         <input type="text" value={this.state.term} onChange=
                             {this.props.onInputChange} />
                     </div>
                 </form>
             </div>
         )
     }
}

这样,子进程将更新父进程的状态onInputChange和onFormSubmit是父进程传递的道具。这可以从子进程中的事件侦听器调用,因此状态将在那里更新。

其他回答

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

 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')}/ >
  }
}

希望它能帮助到别人。

我们可以创建ParentComponent并使用handleInputChange方法来更新ParentComponent的状态。导入ChildComponent并将两个道具从父组件传递给子组件,即handleInputChange函数和count。

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

class ParentComponent extends Component {
  constructor(props) {
    super(props);
    this.handleInputChange = this.handleInputChange.bind(this);
    this.state = {
      count: '',
    };
  }

  handleInputChange(e) {
    const { value, name } = e.target;
    this.setState({ [name]: value });
  }

  render() {
    const { count } = this.state;
    return (
      <ChildComponent count={count} handleInputChange={this.handleInputChange} />
    );
  }
}

现在我们创建了ChildComponent文件,并将其保存为ChildComponent.jsx。这个组件是无状态的,因为子组件没有状态。我们使用prop-types库进行道具类型检查。

import React from 'react';
import { func, number } from 'prop-types';

const ChildComponent = ({ handleInputChange, count }) => (
  <input onChange={handleInputChange} value={count} name="count" />
);

ChildComponent.propTypes = {
  count: number,
  handleInputChange: func.isRequired,
};

ChildComponent.defaultProps = {
  count: 0,
};

export default ChildComponent;

如果你想要更新父组件,

class ParentComponent extends React.Component {
    constructor(props){
        super(props);
        this.state = {
           page: 0
        }
    }

    handler(val){
        console.log(val) // 1
    }

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


class ChildComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
             page: 1
        };
    }

    someMethod = (page) => {
        this.setState({ page: page });
        this.props.onChange(page)
    }

    render() {
        return (
            <Button
                onClick={() => this.someMethod()}
            > Click
        </Button>
      )
   }
}

这里的onChange是一个带有“handler”方法绑定到其实例的属性。我们将方法处理程序传递给子类组件,通过props参数中的onChange属性接收。

onChange属性将在props对象中设置,如下所示:

props = {
    onChange: this.handler
}

并传递给子组件。

所以子组件可以像props. onchange这样访问props对象中的name值。

这是通过使用渲染道具完成的。

现在子组件有一个按钮“Click”,带有一个onclick事件集,用于调用通过props参数对象中的onChange传递给它的处理程序方法。所以现在子类中的this.props.onChange保存了父类中的输出方法。

参考资料和演职员表:Bits and Pieces

只需通过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;

似乎我们只能将数据从父组件传递给子组件,因为React促进单向数据流,但为了让父组件在“子组件”中发生某些事情时更新自己,我们通常使用所谓的“回调函数”。

我们将父类中定义的函数作为“props”传递给子类 从子进程调用该函数,在父进程中触发它 组件。


class Parent extends React.Component {
  handler = (Value_Passed_From_SubChild) => {
    console.log("Parent got triggered when a grandchild button was clicked");
    console.log("Parent->Child->SubChild");
    console.log(Value_Passed_From_SubChild);
  }
  render() {
    return <Child handler = {this.handler} />
  }
}

class Child extends React.Component {
  render() {
    return <SubChild handler = {this.props.handler}/ >
  }
}

class SubChild extends React.Component {
  constructor(props){
   super(props);
   this.state = {
      somethingImp : [1,2,3,4]
   }
  }
  render() {
     return <button onClick = {this.props.handler(this.state.somethingImp)}>Clickme<button/>
  }
}
React.render(<Parent />,document.getElementById('app'));

 HTML
 ----
 <div id="app"></div>

在这个例子中,我们可以通过将函数传递给它的直接子函数来实现数据从子→子→父的传递。