![](/img/trans.png)
[英]React: update component's props from outside of render method without using state
[英]A way to call React component's method from outside (with it's state and props)
我坚持调用我的 clickRemoveHandler。 我的想法是我有两个组件:第一个 - 呈现 header 的布局、导航和页脚组件,第二个 - 计算器,它是我的核心组件,具有数据输入等......在计算器组件中,我有管理 state 的按钮,所以当我点击在布局组件 (div) 的任何位置,我需要调用计算器 function 来操作我的按钮。 代码如下:
class Layout extends Component {
.....
clickHandler = (event) => {
Calculator.clickRemoveHandler(event);
console.log('Clikced')
};
.....
}
class Calculator extends Component {
state = {
currentServiceClass: null,
hoverIndex: null,
btnClicked: false,
selectedService: null
}
currentCursorPosition = {
el: null,
index: null,
rendered: false
}
static clickRemoveHandler = (event) => {
if ((!event.target.hasAttribute("type")) && (this.state.btnClicked)) {
this.currentCursorPosition = {
el: null,
index: null,
rendered: false
};
this.setState({currentServiceClass: null, hoverIndex: null, btnClicked: false})
}
}
....
}
这些组件中有很多逻辑,因此它们太健壮了,无法发布完整代码。 但问题是布局中没有计算器引用,计算器本身是用另一个组件的路由渲染的,所以我不能直接将布局中的任何数据传递给计算器。 我想要的是从布局中调用 static clickRemoveHandler。 我猜 static 是一个使 function 成为全局的选项。 所以它有效,但我收到错误 TypeError: undefined is not an object (evaluating 'Calculator.state.btnClicked')。 正如我所见,这意味着当调用 clickRemoveHandler 时,它与计算器组件没有关联,或者无法访问其 state 和道具。 问题是我怎样才能让它们一起工作? 调用 function 时传递计算器 state 还是有其他更优雅的方法?
我建议您描述的情况(不同级别的不同组件需要访问某些 state 并对其进行操作)使用 React context
。 您也可以查看 state 管理器,例如Redux
或MobX
,但在这种特殊情况下,它会产生开销,因为您的应用程序不是那么“庞大”。 基本上你需要创建一些单独的文件夹(你可以称之为context
),在里面你应该创建上下文本身,导出它并将它包装在你最上层的组件中,这样所有的孩子都可以使用它。
您可以在此处找到示例: https://codesandbox.io/s/spring-glitter-0vzul 。
这是文档的链接: https://reactjs.org/docs/context.html
如果您需要,我可以为您提供更多详细信息
这是一个挑战,但我做到了:布局组件:
state = {
firstMount: false,
clicked: false,
clickedEvt: null
};
clickHandler = (event) => {
console.log('Clikced')
if (this.state.clickedEvt)
this.setState({clicked: false, clickedEvt: null});
else
this.setState({clicked: true, clickedEvt: event.target}, ()=>{setTimeout(() =>
this.setState({clicked: false, clickedEvt: null})
, 50)})
};
<LayoutContext.Provider value={{
clicked: this.state.clicked,
clickedEvt: this.state.clickedEvt,
handleClick: this.clickHandler
}}>
render() {
return(
<div onClick={(event) => this.clickHandler(event)} className="web">
首先我从 Layout 组件调用 handleClick 作为 onclick 事件,然后从计算器再次调用它
componentDidUpdate() {
if (this.context.clicked) {
this.clickRemoveHandler(this.context.clickedEvt)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.