首页 > 解决方案 > 在不同页面路由上的不同组件中反应状态

问题描述

我已经能够在一个名为的特定组件上设置状态,该组件SubmitProject位于特定的路线/submit上。现在我也有一个路由/portfolio,它有一个名为的组件Portfolio我想知道如何让状态从SubmitProject相同,Portfolio你只能与相互嵌套的组件共享状态吗?我最终想要做的是使用表单提交文本以在/submit路线上状态,然后在/portfolio路线中更新相同的状态数据。

我可能接近设计错误,如果一切可能都在 APP 组件中并且我做不同的路由,我对 React 很陌生,所以我肯定需要有关如何设置我的项目的指导。

好的,提前谢谢。

这是我的相关代码

src/components/SubmitProject.js

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

class SubmitProject extends React.Component {
    state = {
        sections:{}
    };
    addSection = section =>{
        const sections = {...this.state.sections};
        sections[`section${Date.now()}`] = section;
        this.setState({
            sections: sections
        });
    }
    render() {
        return(
            <React.Fragment>
                <h1>Submit Project</h1>
                <h2>Enter Project Data</h2>
                <PortfolioForm addSection={this.addSection} />
            </React.Fragment>
        )
    }
}

export default SubmitProject;

src/components/PortfolioForm.js

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

class Portfolio extends React.Component {
    render() {
        return(
            <React.Fragment>
                <h1>Submit Form</h1>
                <FormAdd addSection={this.props.addSection}/>
            </React.Fragment>
        )
    }
}

export default Portfolio;

src/components/FormAdd.js

import React from 'react';

class FormAdd extends React.Component {
    nameRef = React.createRef();

    createSection = (event) =>{
        event.preventDefault();
        const section = {
            name: this.nameRef.current.value
        };
        this.props.addSection(section);
    };  
    render() {
        return(
            <React.Fragment>
                <form onSubmit={this.createSection}>
                    <input type="text" ref={this.nameRef} name="name" placeholder="Name"/>
                    <button type="submit">+ Add Section</button>
                </form>
            </React.Fragment>
        )
    }
}

export default FormAdd;

src/components/Router.js

import React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import Portfolio from './Portfolio';
import SubmitProject from './SubmitProject';
import App from './App';

const Router = () => (
    <BrowserRouter>
        <Switch>
            <Route exact path="/" component={App}/>
            <Route exact path="/portfolio" component={Portfolio}/>
            <Route exact path="/submit" component={SubmitProject}/>
        </Switch>
    </BrowserRouter>
);

export default Router;

src/Portfolio.js

import React from 'react';

class Portfolio extends React.Component {
    //CAN I GET STATE FROM SubmitProject.js FILE IN HERE?
    render() {
        return(
            <React.Fragment>
                <h1>Portfolio Page</h1>
                <h2>List of projects</h2>        
            </React.Fragment>
        )
    }
}

export default Portfolio;

标签: javascriptreactjsstate

解决方案


如果您使用的是 React 16,那么您可以使用 Context API 来解决这个问题。这将涉及对您的代码进行以下调整:

// PortfolioContext.jsx
// Define a PortfolioContext component with initial shared 'sections' state
export default const PortfolioContext = React.createContext(
  sections : {}
);

然后更新您的 SubmitProject 组件以使用该PortfolioContext组件来更新共享sections状态:

// SubmitProject.jsx
// Use the ProtfolioContext component in your SubmitProject component to update
// the shared for use in the Portfolio component
import React from 'react';
import PortfolioForm from './PortfolioForm';
import PortfolioContext from './PortfolioContext';

class SubmitProject extends React.Component {
   constructor (props) {
        super(props)
        this.state = {
             sections:{}
        };
    }

    addSection = section =>{
        const sections = {...this.state.sections};
        sections[`section${Date.now()}`] = section;
        this.setState({
            sections: sections
        });
    }
    render() {
        return(
            { /* Inject the local sections state into provider */ }
            <PortfolioContext.Provider value={this.state.sections}>
                <React.Fragment>
                    <h1>Submit Project</h1>
                    <h2>Enter Project Data</h2>
                    <PortfolioForm addSection={this.addSection} />
                </React.Fragment>
            </PortfolioContext.Provider>
        )
    }
}

export default SubmitProject;

并且还更新您的 Portfolio 组件以使用该PortfolioContext组件来获取共享状态:

// Portfolio.jsx
import React from 'react';
import PortfolioContext from './PortfolioContext';

class Portfolio extends React.Component {
    //CAN I GET STATE FROM SubmitProject.js FILE IN HERE?
    render() {
        return(
            { /* Use the PortfolioContext.Consumer to access sections state */}
            <PortfolioContext.Consumer>
            {
                sections => (
                    <React.Fragment>
                        <h1>Portfolio Page</h1>
                        <h2>List of projects</h2>        
                        { /* here is the shared state - access and render section data as needed. This is just a demonstration to show how the data can be rendered in some way */ }
                        { Object.values(sections || {}).map(section => (<p>JSON.stringify(section)</p>) )}
                    </React.Fragment>
                )
            }
             </PortfolioContext.Consumer>
        )
    }
}

export default Portfolio;

希望有帮助!


推荐阅读