Reputation: 865
I have a program with two different routes (Body.js
andUser.js
) through a function of Body.js
I save a value in the state
named employeeCurrent
and I want to use this employeeCurrent
on the User.js
route.
I wanted to know how to do this, without having to import User.js
into Body.js
because there, the User.js
would appear along with Body.js
.
My Body.js with function:
import React from "react";
import "./Body.css";
import axios from "axios";
import { Link } from "react-router-dom";
class Body extends React.Component {
constructor() {
super();
this.state = {
employee: [],
employeeCurrent: []
};
}
componentDidMount() {
axios
.get("http://127.0.0.1:3004/employee")
.then(response => this.setState({ employee: response.data }));
}
getName = () => {
const { employee } = this.state;
return employee.map(name => (
<Link className="link" to={`/user/${name.name}`}>
{" "}
<div onClick={() => this.add(name)} key={name.id} className="item">
{" "}
<img
className="img"
src={`https://picsum.photos/${name.name}`}
/>{" "}
<h1 className="name"> {name.name} </h1>
</div>{" "}
</Link>
));
};
add = name => {
const nam = name;
this.state.employeeCurrent.push(nam);
console.log(this.state.employeeCurrent);
};
render() {
return <div className="body">{this.getName()}</div>;
}
}
export default Body;
My User.js:
import React from 'react';
import Body from './Body';
class User extends React.Component {
constructor(props) {
super(props);
this.props = {
employeeCurrent: [],
}
}
Someone would can help me ?
Upvotes: 0
Views: 559
Reputation: 2498
The best practice here would be to lift state up to a container component, or to use something like Redux or Apollo or the new React Context and manage a state at the top level. If you don't want to lift state up to Home.js (maybe doesn't belong there), then a container that would render Body.js or User.js, depending on the route.
You can create a layout component eg. DashboardContainer that would manage data for a collection of routes like the following:
<Router>
<Switch>
<DashboardContainer
exact
path="/body"
component={Body}
{...props}
/>
<DashboardContainer
exact
path="/user"
component={User}
{...props}
/>
<Route component={NotFound} />
</Switch>
</Router>
So here we are using the DashboardContainer for /body and /user routes. Then router would pass Body or User components to it which would receive the props and state the container has:
export class DashboardContainer extends React.Component {
state = {
employeeCurrent: null,
};
render() {
const {
drawerOpen,
loggingIn,
authenticated,
component,
user,
history,
...rest
} = this.props;
const { employeeCurrent } = this.state;
return (
<div>
<DashboardNavigation
drawerOpen={this.props.drawerOpen}
history={this.props.history}
authenticated={authenticated}
user={user}
/>
<Route
{...rest}
render={props => React.createElement(
component,
{
...props,
employeeCurrent,
authenticated,
user,
},
)}
/>
</div>)
}
}
Note our Route
exists inside DashboardContainer. Then the router still controls which component you want to render (User.js or Body.js), but data is always passed in. Also including a DashboardNavigation component here to illustrate how this could be used for a layout (or any other form of shared data...).
It is also extendable if you want to create other components that will share the same data or layout, or if you want to protect routes (eg. only render React.createElement if authenticated = true, otherwise render a Redirect
component).
Upvotes: 1
Reputation: 2170
If you want pass your state once and do not going to update it you can stringify it and pass by url.
<Link className='link' to={`/user/${name.name}?employeeCurrent=${JSON.stringify(this.state.employeeCurrent)}`}>
But it is bad practice and used when you do not want to use flux libraries.
So another and correct way is to use redux library and save and manage your employees in there.
Upvotes: 0
Reputation: 36199
You need to lift the state up:
Often, several components need to reflect the same changing data. We recommend lifting the shared state up to their closest common ancestor.
That's exactly what you need to do. Home
should keep employeeCurrent
and pass it to Body
and User
.
Another approach would be to use state management libraries like redux or mobx.
Upvotes: 2