在 React.js 的父组件中使用 react-router 时,如何使用 react context API 将数据从父组件传递到子组件?

Posted

技术标签:

【中文标题】在 React.js 的父组件中使用 react-router 时,如何使用 react context API 将数据从父组件传递到子组件?【英文标题】:How do I use react context API to pass data from parent component to child component when using react-router in the parent component in React.js? 【发布时间】:2019-12-04 18:14:01 【问题描述】:

App.js - 父组件

import React from 'react';
import  BrowserRouter as Router, Switch, Route  from 'react-router-dom';

import ChildComponent1 from './ChildComponent1';
import ChildComponent2 from './ChildComponent2';
import Context from './Context';

class App extends React.Component 
  constructor(props) 
    super(props);
    this.state = 
        messageThatllChange: "changing message",
    ;
  

  render() 
    return (
        <Router>
            <Switch>
                <Context.Provider value=this.state.messageThatllChange>
                    <Route exact path='/' component=ChildComponent1 />
                    <Route path='/chat' component=ChildComponent2 />
                </Context.Provider>
            </Switch>
        </Router>
    );
  


export default App;

ChildComponent1.js - 子组件

import React from 'react';
import Context from './Context';

class Join extends React.Component 
    static contextType = Context;

    constructor(props) 
        super(props);
        console.log(this.context); // this.context returns undefined.
    

    render() 
        return (
            <div>
                /* Something important here */
            </div>
        );
    


// Join.contextType = Context; // tried this too
export default Join;

在尝试打印 this.context 的子组件 1 构造函数中返回 undefined

如何将上下文从父级传递给子级?我做错了什么?

【问题讨论】:

我可以理解反对意见,但在文档页面reactjs.org/docs/context.html#classcontexttype 中没有提到构造函数中this.context 的值将是undefined 【参考方案1】:
import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const Context = React.createContext( message: "hi" );

class Child extends React.Component 
  constructor() 
    super();
    console.log("Constructor: ", this.context); // undefined here
  
  render() 
    const message = this.context;
    return <p>message</p>; // hello here
  


Child.contextType = Context;

function App() 
  return (
    <div className="App">
      <Context.Provider value="hello">
        <Child />
      </Context.Provider>
    </div>
  );


const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

尝试在构造函数中打印上下文返回未定义,但您应该能够像这样在渲染函数中使用上下文。

您可以在此处运行示例:https://codesandbox.io/s/crazy-forest-89bd6?fontsize=14

【讨论】:

【参考方案2】:

尝试重写您的子组件,如下所示:

动态上下文

import React from 'react';
import Context from './Context'; // Context here is the name you defined as Context = React.createContext();

class Join extends React.Component 
    render() 
        let props = this.props;
        let value = this.context;
        return (
            <div>
                /* Something important here */
            </div>
        );
    


Join.contextType = Context; // Context here is the name you defined as Context = React.createContext();
export default Join;

Context.Consumer

import React from 'react';
import  Consumer  from './Context'; // the path is where your context file is

class Join extends React.Component 
    constructor(props) 
        super(props);
    

    render() 
        return (
            <Consumer>
            value => (
                /* Here you can retrieve your messageThatllChange */
                <div>
                    /* Something important here */
                </div>
            )
            </Consumer>
        );
    


export default Join;

【讨论】:

我需要在不同的方法中对传入的值做很多操作,我认为在渲染中做 setState 最终会成为一个 hack(不想这样做) @hungryWolf 所以你的意思是Dynamic Context?让我们试试我的更新答案。

以上是关于在 React.js 的父组件中使用 react-router 时,如何使用 react context API 将数据从父组件传递到子组件?的主要内容,如果未能解决你的问题,请参考以下文章

React js从父事件中更新子状态

React.js + Flux -- 在视图中将回调作为道具传递

React js从父组件更改子组件的状态

无法在类组件 React.js 中使用 useState

在 React.js 表单组件中使用 state 或 refs?

如何使用嵌套路由和私有路由组件在 react.js 中正确构建路由?