wkl*_*klm 298 javascript web-deployment reactjs
我的结构如下:
Component 1
- |- Component 2
- - |- Component 4
- - - |- Component 5
Component 3
Run Code Online (Sandbox Code Playgroud)
组件3应该根据组件5的状态显示一些数据.由于props是不可变的,我不能简单地将它保存在组件1中并转发它,对吧?是的,我读过有关redux的内容,但不想使用它.我希望只有反应就可以解决它.我错了吗?
Iva*_*van 573
对于子父通信,您应该传递一个函数,将状态从父级设置为子级,就像这样
class Parent extends React.Component {
constructor(props) {
super(props)
this.handler = this.handler.bind(this)
}
handler() {
this.setState({
someVar: 'some value'
})
}
render() {
return <Child handler = {this.handler} />
}
}
class Child extends React.Component {
render() {
return <Button onClick = {this.props.handler}/ >
}
}
Run Code Online (Sandbox Code Playgroud)
这样,孩子可以通过调用带有props传递的函数来更新父级的状态.
但是你必须重新考虑组件的结构,因为据我所知,组件5和3不相关.
一种可能的解决方案是将它们包装在更高级别的组件中,该组件将包含组件1和3的状态.该组件将通过props设置较低级别的状态.
Rom*_*man 43
我发现以下工作解决方案将onClick函数参数从child传递给父组件:
传递方法的版本()
//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")
);
}
Run Code Online (Sandbox Code Playgroud)
传递箭头功能的版本
//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")
);
}
Run Code Online (Sandbox Code Playgroud)
mos*_*ony 22
这就是我们如何使用新useState
钩子来做到这一点。方法 - 将状态更改器函数作为道具传递给子组件,并对该函数执行您想做的任何操作
import React, {useState} from 'react';
const ParentComponent = () => {
const[state, setState]=useState('');
return(
<ChildConmponent stateChanger={setState} />
)
}
const ChildConmponent = ({stateChanger, ...rest}) => {
return(
<button onClick={() => stateChanger('New data')}></button>
)
}
Run Code Online (Sandbox Code Playgroud)
我喜欢传递函数的答案,这是一种非常方便的技巧.
另一方面,你也可以使用pub/sub或使用变量,调度程序来实现这一点,就像Flux一样.理论超级简单,有组件5发送组件3正在监听的消息.组件3然后更新其触发重新渲染的状态.这需要有状态的组件,这取决于您的观点,可能是也可能不是反模式.我个人反对他们,并且宁愿其他东西正在监听从上到下的调度和更改状态(Redux这样做,但增加了额外的术语).
import { Dispatcher } from flux
import { Component } from React
const dispatcher = new Dispatcher()
// Component 3
// Some methods, such as constructor, omitted for brevity
class StatefulParent extends Component {
state = {
text: 'foo'
}
componentDidMount() {
dispatcher.register( dispatch => {
if ( dispatch.type === 'change' ) {
this.setState({ text: 'bar' })
}
}
}
render() {
return <h1>{ this.state.text }</h1>
}
}
// Click handler
const onClick = event => {
dispatcher.dispatch({
type: 'change'
})
}
// Component 5 in your example
const StatelessChild = props => {
return <button onClick={ onClick }>Click me</button>
}
Run Code Online (Sandbox Code Playgroud)
与Flux捆绑的调度程序非常简单,只需注册回调并在发生任何调度时调用它们,通过调度上的内容(在上面的简洁示例中,没有payload
调度,只是消息ID).如果这对你更有意义,你可以很容易地将它改编为传统的pub/sub(例如,使用来自事件的EventEmitter或其他版本).
我要感谢最赞同的答案,它给了我自己的问题的想法,基本上是通过箭头功能和从子组件传递参数来实现的:
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')}/ >
}
}
Run Code Online (Sandbox Code Playgroud)
希望它可以帮助某人。
小智 6
我找到了以下可行的解决方案,以通过参数将onClick函数参数从子级传递到父级组件:
家长班:
class Parent extends React.Component {
constructor(props) {
super(props)
// Bind the this context to the handler function
this.handler = this.handler.bind(this);
// Set some state
this.state = {
messageShown: false
};
}
// This method will be sent to the child component
handler(param1) {
console.log(param1);
this.setState({
messageShown: true
});
}
// Render the child component and set the action property with the handler as value
render() {
return <Child action={this.handler} />
}}
Run Code Online (Sandbox Code Playgroud)
子班:
class Child extends React.Component {
render() {
return (
<div>
{/* The button will execute the handler function set by the parent component */}
<Button onClick={this.props.action.bind(this,param1)} />
</div>
)
} }
Run Code Online (Sandbox Code Playgroud)
小智 6
看起来我们只能将数据从父级传递到子级,因为 React 促进了单向数据流,但是为了让父级在其“子组件”发生某些事情时自行更新,我们通常使用所谓的“回调函数”。
我们将在父组件中定义的函数作为“道具”传递给子组件,并从子组件调用该函数在父组件中触发它。
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>
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我们可以让数据从子孩子传递?孩子?parent通过将函数传递给它的直接孩子。
每当您需要在任何级别的子级与父级之间进行通信时,最好使用 context。在父组件中,定义可以由子组件调用的上下文,例如
在您的案例组件的父组件中3
static childContextTypes = {
parentMethod: React.PropTypes.func.isRequired
};
getChildContext() {
return {
parentMethod: (parameter_from_child) => this.parentMethod(parameter_from_child)
};
}
parentMethod(parameter_from_child){
// update the state with parameter_from_child
}
Run Code Online (Sandbox Code Playgroud)
现在在子组件(您的情况下为组件5)中,只需告诉该组件它想使用其父组件的上下文即可。
static contextTypes = {
parentMethod: React.PropTypes.func.isRequired
};
render(){
return(
<TouchableHighlight
onPress={() =>this.context.parentMethod(new_state_value)}
underlayColor='gray' >
<Text> update state in parent component </Text>
</TouchableHighlight>
)}
Run Code Online (Sandbox Code Playgroud)
您可以在回购中找到演示项目
小智 5
我多次使用此页面上评价最高的答案,但是在学习 React 的过程中,我找到了一种更好的方法来做到这一点,无需绑定,也无需在 props 中使用内联函数。
看看这里:
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} />
}
Run Code Online (Sandbox Code Playgroud)
关键在箭头函数中:
handleChange = (someValue) => {
this.setState({someVar: someValue})
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处阅读更多内容。
如果同样的场景没有遍布各处,您可以使用 React 的上下文,特别是如果您不想引入状态管理库带来的所有开销。另外,它更容易学习。不过要小心; 你可能会过度使用它并开始编写糟糕的代码。基本上,您定义一个容器组件(它将为您保留并保留该状态),使所有组件都对向其子级(不一定是直接子级)写入/读取该数据感兴趣。
您也可以正确使用普通的 React。
<Component5 onSomethingHappenedIn5={this.props.doSomethingAbout5} />
Run Code Online (Sandbox Code Playgroud)
将 doSomethingAbout5 传递给组件 1:
<Component5 onSomethingHappenedIn5={this.props.doSomethingAbout5} />
Run Code Online (Sandbox Code Playgroud)
如果这是一个常见问题,您应该开始考虑将应用程序的整个状态移动到其他地方。您有几种选择,最常见的是:
基本上,您不是在组件中管理应用程序状态,而是在发生某些情况更新状态时发送命令。组件也从该容器中提取状态,因此所有数据都是集中的。这并不意味着您不能再使用本地状态,但这是一个更高级的主题。
小智 5
只需通过 props 将父组件的 setState 函数传递给子组件即可。
function ParentComp() {
const [searchValue, setSearchValue] = useState("");
return <SearchBox setSearchValue={setSearchValue} searchValue={searchValue} />;
}
Run Code Online (Sandbox Code Playgroud)
然后在子组件中:
function SearchBox({ searchValue, setSearchValue }) {
return (
<input
id="search-post"
type="text"
value={searchValue}
onChange={(e) => setSearchValue(e.target.value)}
placeholder="Search Blogs ..."
/>
)
}
Run Code Online (Sandbox Code Playgroud)
处理子组件点击的第二个示例:
// We've below function and component in parent component
const clickHandler = (val) => {
alert(`httpRequest sent. \nValue Received: ${val}`);
};
// JSX
<HttpRequest clickHandler={clickHandler} />
Run Code Online (Sandbox Code Playgroud)
这就是从父组件获取函数然后传递一个值并clickHandler
通过它触发的方式。
function HttpRequest({ clickHandler }) {
const [content, setContent] = useState("initialState");
return (
<button onClick={() => clickHandler(content)}>
Send Request
</button>
);
}
export default HttpRequest;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
221997 次 |
最近记录: |