简体   繁体   中英

How to pass a state without to import component ReactJS?

I have a program with two different routes ( Body.js and User.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 ?

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.

Lift State To Container Component

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.

Route Container Pattern

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).

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.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM