【问题标题】:How do I pass data between React Functional Components?如何在 React 功能组件之间传递数据?
【发布时间】:2021-10-29 13:32:42
【问题描述】:

目前,当用户导航到某个页面时,我正在尝试将用户的 name 从一个功能组件 <User/> 组件传递到另一个 <Profile /> 组件.

这是我的代码:

User.js

import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { withRouter } from 'react-router-dom';

function User(props) {
    
    return (
        <div>
            <Link to={`/${props.username}`}>
                <hr />
                <p>
                    ({props.name}) {props.username}
                </p>
            </Link>
        </div>
    )
}


const mapStateToProps = state => ({});

export default connect(mapStateToProps)(withRouter(User));

UsersList.js

import React from 'react';
import { withRouter } from 'react-router-dom';

import User from './User';

function UsersList() {
  return (
    <div>
      <h1>Users</h1>
      <User username="john_smith" name="John Smith"/>
      <User username="james_madison" name="James Madison"/>
      <User username="george_washington" name="George Washington"/>
    </div>
  );
}

export default (withRouter(UsersList));

Feed.js

import React from "react";
import { Container } from "react-bootstrap";
import UsersList from "./users/UsersList";

function Feed() {
  return (
    <div>
      <Container>
        <UsersList/>
      </Container>
    </div>
  );
}

export default Home;

App.js

import React from "react";
import { Route, Switch } from "react-router-dom";
import Feed from './components/Feed';
import Profile from "./components/Profile";
import Root from "./Root";


function App() {
  return (
    <Root>
      <Switch>
        <Route exact path="/" component={Feed} />
        <Route exact path="/:username" component={Profile} />
      </Switch>
    </Root>
  );
}

export default App;

这是当前的&lt;Profile /&gt; 页面 - 我只是想将用户名而不是用户名传递到一对&lt;h1&gt;&lt;/h1&gt;标签中:

Profile.js

import React from "react";
import { Container } from "react-bootstrap";

function Profile(props) {
  return (
    <Container>
      <h1>I SIMPLY WANT TO PASS THE USERS NAME HERE</h1>
    </Container>
  );
}

export default Profile;

感谢任何帮助或指导!

【问题讨论】:

    标签: javascript reactjs components react-props react-functional-component


    【解决方案1】:

    你必须使用 Redux。这就是我喜欢它的方式-

    首先安装redux模块:npm install react-redux

    src/components/Profile.js

    使用 mapStateToProps 函数映射 redux 存储中的用户数据

      import React from "react";
      import { Container } from "react-bootstrap";
      import { connect } from 'react-redux';
    
     function Profile( props) {
     let users = props.users
     let userName = window.location.pathname.substring(1);
     var name;
      users.forEach((element) => {
       if(element['username'] === userName){
       name = element['name'];
     }
     });
       return (
       <Container>
         <h1>I SIMPLY WANT TO PASS THE USERS NAME HERE</h1>
         {name }
       </Container>
        );
      }
      const mapStateToProps = state => ({
       users: state.users,
       });
     export default connect(mapStateToProps)(Profile);
    

    /src/action.js

    这里我已经初始化了所有的用户初始值,理想情况下你将从另一个系统获得的用户数据,在这种情况下你将使用 Thunk 或 Saga 进行副作用操作

       export const LOAD_USER = 'LOAD_USER';
    
     const users = [{ username:'john_smith', name: 'John Smith' }, 
                { username:'james_madison', name: 'James Madison' }, 
                {username:'george_washington', name: 'George Washington'}];
    
       export const loadeUser = () => ({
       type: LOAD_USER,
       payload: { users },
       });
    

    /src/reducer.js

    我只是将所有用户数据传递给状态对象

         import { LOAD_USER } from './actions';
    
        export const users = (state = [], action) => {
       const { type, payload } = action;
       switch (type) {
       case LOAD_USER :{
        const { users } = payload;
        return users;
       }
       default:
        return state;
      }
      }
    

    /src/components/User.js

      import React from 'react';
      import { Link } from 'react-router-dom';
    
     function User({user}) {
      return (
        <div>
            <Link to={`/${user.username}`}>
                <hr />
                <p>
                    ({user.name}) {user.username}
                </p>
            </Link>
        </div>
        )
      }
      export default User;
    

    /src/components/UsersList.js

    这里我们必须同时使用 mapDispatchToProps 和 mapStateToProps 以便通过 useEffect 钩子在组件加载时执行调度操作。

        import React, { useEffect } from 'react';
        import { withRouter } from 'react-router-dom';
        import { loadeUser } from '../actions';
        import { connect } from 'react-redux';
        import User from './User';
    
    
      function UsersList({ users = [] , startLoadingUsers}) {
       useEffect(() => {
       startLoadingUsers();
       }, []);
    
     return (
      <div>
      <h1>Users</h1>
      { 
        users.map(user => <User user={user} />)
      }
      </div>
      );
     }
    
     const mapStateToProps = state => ({
      users: state.users,
     });
    
    const mapDispatchToProps = dispatch => ({
     startLoadingUsers: () => dispatch(loadeUser()),
    });
    
    export default connect(mapStateToProps, mapDispatchToProps) 
    (withRouter(UsersList));
    

    /src/App.js

    使用 BrowserRouter 环绕不同的路由

       import React from "react";
      import { Route, Switch,BrowserRouter as Router, } 
       from "react-router-dom";
      import Feed from './components/Feed';
       import Profile from "./components/Profile";
    
       function App() {
       return (
       <Router>
         <Switch>
          <Route exact path="/" component={Feed} />
          <Route exact path="/:username" component={Profile} />
          </Switch>
        </Router>
       );
      }
     export default App;
    

    /src/index.js

    最后,将 store 作为 App 组件的包装器挂钩,以便所有组件都可以使用 Redux store,这由 Provider 完成。

           import React from 'react';
           import ReactDOM from 'react-dom';
           import App from './App';
            import { Provider } from 'react-redux';
           import { configureStore } from './store';
    
           const store = configureStore();
    
           ReactDOM.render(
           <Provider store={store}>
             <App />
           </Provider>,
            document.getElementById('root')
           );
    

    /src/store.js

            import { createStore, combineReducers } from 'redux';
            import { users } from './reducer';
    
             const reducers = {
             users,
             };
    
            const rootReducer = combineReducers(reducers);
            export const configureStore = () =>
             createStore(
               rootReducer,
                window.__REDUX_DEVTOOLS_EXTENSION__ &&
                window.__REDUX_DEVTOOLS_EXTENSION__(),
            );
    

    最后的结果

    【讨论】:

    【解决方案2】:

    这是一个使用全局状态管理器的示例。考虑像@​​987654322@ 或context providers 这样的东西。就功能组件而言,越来越多的人正在远离 redux 并使用带有 useContext 钩子 (more information can be found here) 的上下文提供程序。就快速解决方案而言,始终可以使用App 状态,但在尝试将它们传递到组件层次结构的同一级别时,传递道具可能会变得非常混乱。

    【讨论】:

      猜你喜欢
      • 2020-01-31
      • 2021-10-14
      • 2020-12-27
      • 2019-09-09
      • 2018-02-15
      • 1970-01-01
      • 2022-01-20
      • 2019-01-04
      • 2021-10-26
      相关资源
      最近更新 更多