如何在 React 功能组件之间传递数据?

Posted

技术标签:

【中文标题】如何在 React 功能组件之间传递数据?【英文标题】:How do I pass data between React Functional Components? 【发布时间】: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;

感谢任何帮助或指导!

【问题讨论】:

【参考方案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__(),
        );

最后的结果

【讨论】:

@anks,很高兴听到这个消息,请接受这个答案:) 没有足够的声望 - 我试过了! @anks meta.stackexchange.com/questions/86978/…【参考方案2】:

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

【讨论】:

以上是关于如何在 React 功能组件之间传递数据?的主要内容,如果未能解决你的问题,请参考以下文章

React 功能组件 - 当组件返回元素数组时,如何将 refs 传递回父级?

使用 useState 在 React 组件之间传递值

无法将数据从子功能组件传递到反应父组件(React.js)[重复]

如何在 React Native 中的组件之间传递数据

如何从 React 中的子组件更新父组件(功能)

将数据从子功能组件传递到父组件 - React/Typescript