[英]React - Call function from 'sibling' component
这是我当前的 model,请查看
import component 1 & 2
export default class App extends Component {
render() {
return (
<Component1/>
<Component2/>
);
}
}
在组件 1 中,我有一个 function:运行此 function 后的 pushData(),我想在组件 2 上使用 fetchData() 执行下一步,但我找不到从 1 引用 2 的方法,因为它们不是父级-孩子?!
这可以通过多种方式完成,考虑到上面共享的代码具有基于 Class 的实现,我建议采用以下解决方案。
现在 Component1 将拥有自己的 function 来推送数据,我们称其为 function pushData 。 一旦推送数据的逻辑结束,调用传递的 prop function dataPushed 。 此道具将使用当前状态更新父级 state,即数据已推送,并将 state 变量设置为 true。
现在这个state这个变量已经传给了Component2,在Component2中使用ComponentDidUpdate。我们可以知道从Component1传来的dataPush的state,如果为真,就可以调用Component2内部的function来获取数据。
获取数据后,立即调用传递给此 Component2 的 prop 让父级知道已获取最新数据,并将 dataPushed 的父级变量 state 设置为 false。
忽略 function 和使用的变量名,随意使用你的。
我用代码创建了一个沙箱,
https://codesandbox.io/s/affectionate-forest-5kc68?file=/src/App.js
我希望这能解决你的问题。 如果您仍然对上述任何解释感到困惑或不清楚,请告诉我。
从架构上讲,您尝试做的不是一个好主意。
例如,如果您更改具有您要使用的 function 的组件,您需要记住更新使用此 function 的任何依赖项。这变得难以维护。
React 道具实际上使使用依赖注入模式解决这个问题变得非常容易。 如果你不熟悉依赖注入,它本质上意味着依赖是自上而下的,需要这些依赖的组件不知道这个依赖在哪里,也不会出去获取它们。 它只是获取传入的依赖项。
您可以将 function 提升一个级别并让它存在于父组件中,而不是尝试使用存在于同级组件中的方法。 与 state 相同。
想象一下这位家长:
class Container extends React.Component {
state = {
counter: 0
};
reallyCoolFunction = () => {
this.setState({ counter: this.state.counter + 1 });
};
render() {
return (
<>
<Cool
counter={this.state.counter}
doCoolThing={this.reallyCoolFunction}
/>
<Wannabe doCoolThing={this.reallyCoolFunction} />
</>
);
}
}
上面的Container
组件创建了 function 并将其传递给两个组件。 然后每个组件会在需要时调用 function,例如:
class Wannabe extends React.Component {
handleClick = () => {
this.props.doCoolThing();
};
render() {
return (
<div>
<h2>Wannabe</h2>
<button onClick={this.handleClick}>click</button>
</div>
);
}
}
然后在你的应用程序中拥有 function 的组件得到传递的相关道具:
class Cool extends React.Component {
handleClick = () => {
this.props.doCoolThing();
};
render() {
return (
<div>
<h2>Cool</h2>
<p>{this.props.counter}</p>
<button onClick={this.handleClick}>click</button>
</div>
);
}
}
如果您的应用程序正在增长并且您计划对其进行一段时间的开发,您可能需要考虑实施 state 管理解决方案,例如Redux 。 使state管理更简单。
如果您要使用功能组件而不是 class 组件,则可以使用第三种选择,那就是构建您自己的自定义挂钩。 如果您还不熟悉钩子,那可能有点学习曲线。 您可以阅读React hooks 文档了解如何做到这一点。
我已经创建了一个描述的容器组件和子组件示例的演示。 在此示例中,它们都能够更新Cool
组件中显示的 state: https://codesandbox.io/s/dry-hill-r425r?file=/src/App.js
您必须传递来自父级的回调,该回调将在您的第一个 function 执行后调用,更新父级的 state 然后将道具传递给第二个组件以通知它。
import React from "react";
class Component1 extends React.Component {
componentDidMount() {
// execute your first function here
if (this.props.onPushData) {
this.props.onPushData();
}
}
render() {
return <p>Component1</p>;
}
}
class Component2 extends React.Component {
componentDidUpdate(prevProps) {
if (prevProps.dataPushed !== this.props.dataPushed) {
if (this.props.dataPushed) {
// execute your second function here
}
}
}
render() {
return <p>Component2</p>;
}
}
export default class extends React.Component {
state = {
dataPushed: false
}
handleDataPush = () => {
this.setState({ dataPushed: true })
}
render() {
return (
<div>
<Component1 onPushData={this.handleDataPush} />
<Component2 dataPushed={this.state.dataPushed} />
</div>
);
}
}
这是一个 例子
在 component1 中访问 component2 的 function 的一种方法是使用refs
。
代码片段:
export default class App extends React.Component {
ref = React.createRef();
render() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Component1 comp2Ref={this.ref} />
<Component2 ref={this.ref} />
</div>
);
}
}
// Component1.js
export default class Component1 extends React.Component {
pushData = () => {
// make the first api call..
console.log("comp 1 fun");
// now call component2 function
console.log(this.props);
this.props.comp2Ref.current.fetchData();
};
render() {
return (
<div className="App">
<h1>component 1</h1>
<button onClick={this.pushData}>push data button</button>.
</div>
);
}
}
// Component2.js
export default class Component2 extends React.Component {
fetchData = () => {
console.log("comp 2 fun");
};
render() {
return (
<div className="App">
<h1>component 2</h1>
</div>
);
}
}
处理您的场景的最佳方法是将fetchData
function 提升到父级并将其作为 prop 传递给component2
。
像这样
export default class App extends React.Component {
state = {
data: []
};
fetchData = () => {
// fetch the data and update the state(data) and pass it as prosp in component 2
console.log("comp 2 fun");
};
render() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Component1 fetchData={this.fetchData} />
<Component2 data={this.state.data} fetchData={this.fetchData} />
</div>
);
}
}
// Component 1 pushData function
...
pushData = () => {
// make the first api call..
console.log("comp 1 fun");
// now call component2 function
console.log(this.props);
this.props.fetchData();
};
...
从长远来看,我建议您将Redux添加到当前堆栈,React 在使用大层次结构组件进行扩展以及与后端 API 集成方面存在局限性。
所以如果你正在寻找一个真正的项目在生产中,是时候切换到React-Redux
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.