我的结构如下所示:
Component 1
- |- Component 2
- - |- Component 4
- - - |- Component 5
Component 3
组件3应该根据组件5的状态显示一些数据。
因为道具是不可变的,我不能简单地在组件1中保存它的状态并转发它,对吗?是的,我读过Redux,但我不想使用它。我希望只用react就能解决这个问题。我错了吗?
我的结构如下所示:
Component 1
- |- Component 2
- - |- Component 4
- - - |- Component 5
Component 3
组件3应该根据组件5的状态显示一些数据。
因为道具是不可变的,我不能简单地在组件1中保存它的状态并转发它,对吗?是的,我读过Redux,但我不想使用它。我希望只用react就能解决这个问题。我错了吗?
当前回答
似乎我们只能将数据从父组件传递给子组件,因为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>
在这个例子中,我们可以通过将函数传递给它的直接子函数来实现数据从子→子→父的传递。
其他回答
我已经多次使用这个页面的顶级答案,但在学习React的时候,我发现了一个更好的方法,没有绑定,也没有道具内的内联函数。
看看这里:
class Parent extends React.Component {
constructor() {
super();
this.state = {
someVar: value
}
}
handleChange = (someValue) => {
this.setState({someVar: someValue})
}
render() {
return <Child handler={this.handleChange} />
}
}
export const Child = ({handler}) => {
return <Button onClick={handler} />
}
键在一个箭头函数中:
handleChange = (someValue) => {
this.setState({someVar: someValue})
}
你可以在这里阅读更多。
我们可以通过将一个函数作为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是父进程传递的道具。这可以从子进程中的事件侦听器调用,因此状态将在那里更新。
在React中,数据不能从子节点传递到父节点。数据必须从父节点传递给子节点。在这种情况下,您可以使用内置的Context API或第三方状态管理解决方案,如Redux、Mobx或Apollo GraphQL。然而,如果你的应用程序结构太小,你可以将数据存储在你的父元素中,然后通过prop drilling将其发送给你的子元素。但如果你的项目比较大,就会很混乱。
<Footer
action={()=>this.setState({showChart: true})}
/>
<footer className="row">
<button type="button" onClick={this.props.action}>Edit</button>
{console.log(this.props)}
</footer>
Try this example to write inline setState, it avoids creating another function.
我是这样做的:
type ParentProps = {}
type ParentState = { someValue: number }
class Parent extends React.Component<ParentProps, ParentState> {
constructor(props: ParentProps) {
super(props)
this.state = { someValue: 0 }
this.handleChange = this.handleChange.bind(this)
}
handleChange(value: number) {
this.setState({...this.state, someValue: value})
}
render() {
return <div>
<Child changeFunction={this.handleChange} defaultValue={this.state.someValue} />
<p>Value: {this.state.someValue}</p>
</div>
}
}
type ChildProps = { defaultValue: number, changeFunction: (value: number) => void}
type ChildState = { anotherValue: number }
class Child extends React.Component<ChildProps, ChildState> {
constructor(props: ChildProps) {
super(props)
this.state = { anotherValue: this.props.defaultValue }
this.handleChange = this.handleChange.bind(this)
}
handleChange(value: number) {
this.setState({...this.state, anotherValue: value})
this.props.changeFunction(value)
}
render() {
return <div>
<input onChange={event => this.handleChange(Number(event.target.value))} type='number' value={this.state.anotherValue}/>
</div>
}
}