I have been able to setState on a specific component called SubmitProject
which lives at a specific route /submit
. Now I also have a route /portfolio
that has a component called Portfolio
I am wondering how do I get the state from SubmitProject
to be the same on Portfolio
Can you only share state with Components that are nested within each other. What I am ultimately trying to do is use a form to submit text to state on the /submit
route and then have that same state data update in the /portfolio
route.
I could be approaching the design wrong, Should everything maybe be in APP Component and I do the Routing different, I am very new to React, so I defintely need guidance on how to setup my project.
Ok Thanks ahead of time.
Here is my relevant code
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;
If you're using React 16, then you could resolve this by using the Context API. This would involve making the following adjustments to your code:
// PortfolioContext.jsx
// Define a PortfolioContext component with initial shared 'sections' state
export default const PortfolioContext = React.createContext(
sections : {}
);
Then update your SubmitProject component to use the PortfolioContext
component to update the shared sections
state:
// 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;
And also update your Portfolio component to use the PortfolioContext
component to get the shared state:
// 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;
Hope that helps!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.