如何在反应中将信息传递给嵌套组件?
Posted
技术标签:
【中文标题】如何在反应中将信息传递给嵌套组件?【英文标题】:How to pass information to nested components in react? 【发布时间】:2018-06-17 20:10:45 【问题描述】:说我有
<component1>
<component2>
<component3>
<component4>
(其中component1有一个子component2,component2有一个子component3,component3有一个子component4)
并说我想将一些东西从 component1 传递到 component4 。我需要将道具传递给链条吗?所以组件1->组件2->组件3->组件4
?
请注意:
这些组件不在同一个文件中。所以在component1.js中我指的是<component2>
,在component2.js中我指的是<component3>
等等。
【问题讨论】:
要么使用 redux 商店。control1
, control2
等是那些组件吗?
@NanduKalidindi 是的修改问题
所以我需要使用redux、actions和reducers来传递一些简单的信息?叹息..
component1 对 component4 一无所知,那么它应该如何传递一些东西给它呢?您可能需要重新考虑您的架构,但您没有提供足够的信息来提供任何建议。
【参考方案1】:
这里有两个主要选项:
-
传递道具。
使用
context
API
使用props
,您还有两个主要选项:
你可以通过 props 隐式传递
<Parent>
<ChildOne ...props>
<ChildTwo ...props>
</ChildTwo>
</ChildOne>
</Parent>
为隐式 props 运行 sn-p:
const ChildTwo = props => (
<div>`Child two says: $props.myProp`</div>
);
const ChildOne = props => (
<div>
<ChildTwo ...props />
</div>
);
const Parent = props => (
<div>
<ChildOne ...props />
</div>
);
ReactDOM.render(<Parent myProp="hi there" />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
或者说清楚
<Parent>
<ChildOne propOne=propOne>
<ChildTwo propOne=propOne>
</ChildTwo>
</ChildOne>
</Parent>
为显式 props 运行 sn-p:
const ChildTwo = (props) => (
<div>`Child two says: $props.myProp`</div>
);
const ChildOne = props => (
<div>
<ChildTwo myProp=props.myProp />
</div>
);
const Parent = props => (
<div>
<ChildOne myProp=props.myProp />
</div>
);
ReactDOM.render(<Parent myProp="hi there" />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
至于上下文 API,您可以跳过关卡并从祖父母那里“抓取”道具。 这就是
react-redux
does behind the scenes。
上下文 API 的运行示例:
const ChildTwo = (props, context) => (
<div>`Child two says: $context.myProp`</div>
);
ChildTwo.contextTypes = myProp: React.PropTypes.string
const ChildOne = props => (
<div>
<ChildTwo />
</div>
);
class Parent extends React.Component
getChildContext()
const myProp = this.props;
return myProp ;
render()
return (
<div>
<ChildOne />
</div>
);
Parent.childContextTypes =
myProp: React.PropTypes.string
;
ReactDOM.render(<Parent myProp="hi there" />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
请注意,此示例使用 react v15,React.PropTypes
的语法已更改,因为 react v16 PropTypes
不再是 react
库的一部分,它已被提取到另一个库 @987654338 @.
另请注意,文档advise against the usage of the context API:
如果您不是经验丰富的 React 开发人员,请不要使用上下文。那里 通常是仅使用道具实现功能的更好方法 和状态。
【讨论】:
【参考方案2】:你可以使用 React 的内置 Context API
,虽然我不建议你过分依赖它,因为这要么会被弃用,要么会成为一个完全稳定的功能。截至目前,Facebook 在他们的文档WARNING 中警告用户。如果没有这个问题,API 就非常棒了,它有助于维护整洁的代码,而无需一直将 props 发送给预期的后代。
CONTEXT API
组件 1
class Component1 extends React.Component
getChildContext()
return
yourProp: "someValue" // you can also add a function like yourProp: someFunc
;
render()
<Component2 />
Component1.childContextTypes =
yourProp: PropTypes.string
;
组件 2
class Component2 extends React.Component
render()
return (
<Component3 />
);
组件 3
class Component3 extends React.Component
render()
return (
<Component4 />
);
组件4
class Component4 extends React.Component
render()
return (
<div>
this.context.yourProp
</div>
);
Component4.contextTypes =
yourProp: PropTypes.string
;
如果你不选择使用这个,有很多策略。
REDUX 事件发射器 将道具一路传给后代【讨论】:
【参考方案3】:是的,只使用 React 你需要通过每个组件传递 props,即使组件不使用该 props。因此,在您的示例中, control2 和 control3 并不关心道具,而是需要将其传递下去。以下是您需要做的事情。
<Control1 test=this.state.test>
<Control2 test=this.props.test>
<Control3 test=this.props.test>
<Control4 test=this.props.test />
</Control3>
</Control2>
</Control1>
这可能会很麻烦,所以redux 可以提供帮助。
【讨论】:
这些组件不在同一个文件中。所以在 component1.js 我指的是以上是关于如何在反应中将信息传递给嵌套组件?的主要内容,如果未能解决你的问题,请参考以下文章