从子组件在父级上执行setState的建议模式是什么.
var Todos = React.createClass({
getInitialState: function() {
return {
todos: [
"I am done",
"I am not done"
]
}
},
render: function() {
var todos = this.state.todos.map(function(todo) {
return <div>{todo}</div>;
});
return <div>
<h3>Todo(s)</h3>
{todos}
<TodoForm />
</div>;
}
});
var TodoForm = React.createClass({
getInitialState: function() {
return {
todoInput: ""
}
},
handleOnChange: function(e) {
e.preventDefault();
this.setState({todoInput: e.target.value});
},
handleClick: function(e) {
e.preventDefault();
//add the new todo item
},
render: function() {
return <div>
<br />
<input type="text" value={this.state.todoInput} onChange={this.handleOnChange} />
<button onClick={this.handleClick}>Add Todo</button>
</div>;
}
});
React.render(<Todos />, document.body)
Run Code Online (Sandbox Code Playgroud)
我有一系列待办事项,它们保持在父母的状态.我想访问父的状态,并从增加新的待办事项,TodoForm
的handleClick
组成部分.我的想法是在父级上执行一个setState,它将呈现新添加的待办事项.
Dee*_*pak 64
在您的父级中,您可以创建一个函数addTodoItem
,其中将执行所需的setState,然后将该函数作为props传递给子组件.
var Todos = React.createClass({
...
addTodoItem: function(todoItem) {
this.state.todos.push(todoItem);
this.setState({todos: this.state.todos});
},
render: function() {
...
return <div>
<h3>Todo(s)</h3>
{todos}
<TodoForm addTodoItem={this.addTodoItem} />
</div>
}
});
var TodoForm = React.createClass({
handleClick: function(e) {
e.preventDefault();
this.props.addTodoItem(this.state.todoInput);
this.setState({todoInput: ""});
},
...
});
Run Code Online (Sandbox Code Playgroud)
你可以addTodoItem
在TodoForm的handleClick中调用.这将在父级上执行一个setState,它将呈现新添加的待办事项.希望你明白这个主意.
Nic*_*eat 12
对于那些使用 React Hook 保持状态的人useState
,我调整了上面的建议,在下面制作了一个演示滑块应用程序。在演示应用程序中,子滑块组件维护父组件的状态。
该演示还使用了useEffect
钩子。(不太重要的是,useRef
钩子)
import React, { useState, useEffect, useCallback, useRef } from "react";
//the parent react component
function Parent() {
// the parentState will be set by its child slider component
const [parentState, setParentState] = useState(0);
// make wrapper function to give child
const wrapperSetParentState = useCallback(val => {
setParentState(val);
}, [setParentState]);
return (
<div style={{ margin: 30 }}>
<Child
parentState={parentState}
parentStateSetter={wrapperSetParentState}
/>
<div>Parent State: {parentState}</div>
</div>
);
};
//the child react component
function Child({parentStateSetter}) {
const childRef = useRef();
const [childState, setChildState] = useState(0);
useEffect(() => {
parentStateSetter(childState);
}, [parentStateSetter, childState]);
const onSliderChangeHandler = e => {
//pass slider's event value to child's state
setChildState(e.target.value);
};
return (
<div>
<input
type="range"
min="1"
max="255"
value={childState}
ref={childRef}
onChange={onSliderChangeHandler}
></input>
</div>
);
};
export default Parent;
Run Code Online (Sandbox Code Playgroud)
对于使用useState
insideArrow Functional Components
启用的任何人TypeScript
,这里有一个简单的示例,说明如何将父级的状态设置器函数传递给子级,并调用它以在适当的时间从子级设置父级的状态 -
父组件:
import {useState} from "react";
const ParentComponent = () => {
const [hasParentStateChange, setHasParentStateChange] = useState<boolean>(false);
return (
<div>
Parent's view: {String(hasParentStateChange)}
<ChildComponent
hasParentStateChange={hasParentStateChange}
setHasParentStateChange={setHasParentStateChange} // <---- Passing parent's state setter over
/>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
子组件:
interface PropsDefinition {
hasParentStateChange: boolean;
setHasParentStateChange(data: boolean): void;
}
const ChildComponent = (props: PropsDefinition) => {
return (
<div>
<div>
Child's view: {String(props.hasParentStateChange)}
</div>
<button
onClick={() => props.setHasParentStateChange(!props.hasParentStateChange)} // <---- Invoking parent's state setter
>
Toggle parent state from child
</button>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
这些都是基本正确的,我只是想我会指出新的(ish)官方反应文件基本上建议: -
对于在React应用程序中发生变化的任何数据,应该有一个"真实来源".通常,首先将状态添加到需要渲染的组件中.然后,如果其他组件也需要它,您可以将它提升到最近的共同祖先.您应该依赖自上而下的数据流,而不是尝试在不同组件之间同步状态.
请参阅https://reactjs.org/docs/lifting-state-up.html.该页面也通过一个例子.
您可以在父组件中创建addTodo函数,将其绑定到该上下文,将其传递给子组件并从那里调用它.
// in Todos
addTodo: function(newTodo) {
// add todo
}
Run Code Online (Sandbox Code Playgroud)
然后,在Todos.render中,你会这样做
<TodoForm addToDo={this.addTodo.bind(this)} />
Run Code Online (Sandbox Code Playgroud)
用TodoForm调用它
this.props.addToDo(newTodo);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
52308 次 |
最近记录: |