Javascript React:父组件在子组件中道具,而不显式传递
是否可以让父组件的道具在子组件中可用,而无需向下传递它们 我试图实现一个提供者模式,以便访问其子组件中的所有提供者道具。 例: 假设下面的提供者compJavascript React:父组件在子组件中道具,而不显式传递,javascript,reactjs,Javascript,Reactjs,是否可以让父组件的道具在子组件中可用,而无需向下传递它们 我试图实现一个提供者模式,以便访问其子组件中的所有提供者道具。 例: 假设下面的提供者compFetchProvider将自己获取数据和主题道具,并且当任何子组件被它包围时,我希望访问子组件中的道具“数据”和“主题”。我们如何才能做到这一点 class FetchProvider { proptypes= { data: PropTypes.shape({}), theme: PropTypes.shape(
FetchProvider
将自己获取数据和主题道具,并且当任何子组件被它包围时,我希望访问子组件中的道具“数据”和“主题”。我们如何才能做到这一点
class FetchProvider
{
proptypes= {
data: PropTypes.shape({}),
theme: PropTypes.shape({})
}
render()
{
// do some
}
mapStateToProps()
{
return {data, theme};
}
}
class ChildComponent
{
proptypes= {
name: PropTypes.shape({})
}
render()
{
const{data, them} = this.props; // is this possible here?
// do some
}
}
如果我试着按照下面的方式来描述上面的组件
<FetchProvider>
<ChildComponent name="some value"/> //how can we access parent component props here? without passing them down
<FetchProvider/>
//我们如何在这里访问父组件道具?不传下去
您可以使用React.Children
迭代子元素,并使用React.cloneElement
将要发送的任何道具传递给新的克隆元素
例:
类父级扩展React.Component{
建造师(道具){
超级(道具);
}
render(){
const{children}=this.props;
const newChildren=React.Children.map(Children,child=>
cloneElement(child,{myProp:'test'});
返回(
{newChildren}
)
}
}
您正在寻找:
class MyParent extends Component {
render() {
return <MyChild {...this.props}>
// child components
</MyChild>
}
}
类MyParent扩展组件{
render(){
返回
//子组件
}
}
这会将传递到MyParent
的所有道具传递给正在呈现的MyChild
。这正是全部内容
消费者
可以访问提供者
公开的数据,无论其嵌套有多深
// Context lets us pass a value deep into the component tree
// without explicitly threading it through every component.
// Create a context for the current theme (with "light" as the default).
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
// Use a Provider to pass the current theme to the tree below.
// Any component can read it, no matter how deep it is.
// In this example, we're passing "dark" as the current value.
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
}
// A component in the middle doesn't have to
// pass the theme down explicitly anymore.
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton(props) {
// Use a Consumer to read the current theme context.
// React will find the closest theme Provider above and use its value.
// In this example, the current theme is "dark".
return (
<ThemeContext.Consumer>
{theme => <Button {...props} theme={theme} />}
</ThemeContext.Consumer>
);
}
//上下文允许我们将值传递到组件树的深处
//没有显式地将其穿过每个组件。
//为当前主题创建上下文(默认为“light”)。
const ThemeContext=React.createContext('light');
类应用程序扩展了React.Component{
render(){
//使用提供程序将当前主题传递到下面的树。
//任何组件都可以读取它,无论它有多深。
//在本例中,我们将“暗”传递为当前值。
返回(
);
}
}
中间的组件不必
//再明确地传递主题。
功能工具栏(道具){
返回(
);
}
功能按钮(道具){
//使用使用者读取当前主题上下文。
//React将在上面找到最近的主题提供程序并使用其值。
//在本例中,当前主题为“暗”。
返回(
{主题=>}
);
}
下面是一个小例子:
注意这是react v16上下文API。您的用例可以通过使用来解决。在上下文的帮助下,由提供者包装的任何子级都可以是提供者提供的数据的使用者 在你的情况下,你可以像这样使用它 context.js
export const FetchContext = React.createContext();
Provider.js
import { FetchContext } from 'path/to/context.js';
class FetchProvider extends React.Component
{
proptypes= {
data: PropTypes.shape({}),
theme: PropTypes.shape({})
}
render()
{
const { data, theme, children } = this.props;
return (
<FetchContext.Provider value={{ data, theme}}>
{children}
</FetchContext.Provider>
)
}
mapStateToProps()
{
return {data, theme};
}
}
无论如何,您都在将prop“myProp”从父级传递给子级。我在父级即FetchProvider中使用了类似的React上下文概念,使用了ChildContextTypes和getChildContext函数。并使用HOC装饰器将上下文值向下注入到子级。以这种方式使用React上下文似乎非常干净。@Matt,这是React中提供的新上下文API,从版本16.3.0开始提供。如果您使用的react版本高于此版本,则应以这种方式使用上下文。
import { FetchContext } from 'path/to/context.js';
class FetchProvider extends React.Component
{
proptypes= {
data: PropTypes.shape({}),
theme: PropTypes.shape({})
}
render()
{
const { data, theme, children } = this.props;
return (
<FetchContext.Provider value={{ data, theme}}>
{children}
</FetchContext.Provider>
)
}
mapStateToProps()
{
return {data, theme};
}
}
class ChildComponent extends React.Component
{
proptypes= {
name: PropTypes.shape({})
}
render()
{
const{data, them} = this.props; // use it from props here
// do some
}
}
export default (props) => (
<FetchContext.Consumer>
{({ data, theme }) => <ChildComponent {...props} data={data} theme={theme} />}
</FetchContext.Consumer>
)
class ChildComponent extends React.Component
{
proptypes= {
name: PropTypes.shape({})
}
render()
{
const{data, them} = this.props; // use it from props here
// do some
}
}
const mapStateToProps = (state) => {
return {
data: state.data,
theme: state.theme
}
}