React中非父子组件如何传值?如何将datacame从SearchingData传到Search
解决方案
你当前项目已经集成了react-redux,优先用现有状态管理实现跨组件传值即可,不需要新增额外依赖,操作步骤如下:
步骤1:修改Redux的search模块,新增筛选数据相关状态和Action
首先在你的search reducer定义文件里,新增filteredUsers字段,以及对应的更新Action:
// 假设你是在searchReducer.ts里定义 export interface ISearch { search: any[]; // 你原有全量用户的字段 filteredUsers: any[]; // 新增:存筛选后的用户数据 } // 新增Action类型 const SET_FILTERED_USERS = 'search/setFilteredUsers'; // 新增Action生成函数 export const setFilteredUsers = (users: any[]) => ({ type: SET_FILTERED_USERS, payload: users }); // 在reducer里加对应的处理逻辑 const initialState: ISearch = { search: [], filteredUsers: [] // 初始值为空 } export default function searchReducer(state = initialState, action: any) { switch(action.type) { // 你原有其他case case SET_FILTERED_USERS: return { ...state, filteredUsers: action.payload } default: return state; } }
步骤2:修改SearchingData组件,把筛选后的数据存入Redux
删掉组件内部的datacame本地状态,筛选完成后直接dispatch Action把数据存到Redux:
import React, { ChangeEvent } from "react"; import { useDispatch } from "react-redux"; // 新增导入useDispatch import { setFilteredUsers } from "你的searchReducer路径"; // 导入刚才新增的Action type searchData = { handleSearch: (e: ChangeEvent<HTMLInputElement>) => void; seardhingDTata: any; seardhDTata: string; }; const SearchingData: React.FC<searchData> = ({ handleSearch, seardhingDTata, seardhDTata, }) => { const dispatch = useDispatch(); // 新增获取dispatch const UpdateData = (e: ChangeEvent<HTMLInputElement>) => { handleSearch(e); }; // 删掉原来的datacame本地状态 const serachData = () => { let defaultData = seardhingDTata; const filterdserachData = seardhDTata ? defaultData.filter((use: any) => use.UserName.toLowerCase().startsWith(seardhDTata) ) : defaultData; // 筛选完成后直接存到Redux dispatch(setFilteredUsers(filterdserachData)); }; return ( <React.Fragment> <div> <input type="text" onChange={UpdateData} /> <button className="btn btn-blue btn-sm" onClick={serachData}> Serach </button> </div> </React.Fragment> ); }; export default SearchingData;
步骤3:修改Search组件,从Redux读取筛选后的数据渲染表格
import React, { ChangeEvent } from "react"; import { useEffect, useState } from "react"; import { useSelector, useDispatch } from "react-redux"; import SearchingData from "./SearchingData"; import { searchActions } from "你的searchAction路径"; // 你原有导入 const Search: React.FC = () => { let dispatch = useDispatch(); //Read the Data from Store,现在多取一个filteredUsers字段 let readingStateData: searchReducsers.ISearch = useSelector( (state: { searchingData: searchReducsers.ISearch }) => { return state.searchingData; } ); // Update the Data useEffect(() => { dispatch(searchActions.fetchUser()); }, []); const [seardhDTata, setseardhDTata] = useState(""); const handlesearching = (e: ChangeEvent<HTMLInputElement>) => { setseardhDTata(e.target.value); }; // 渲染逻辑:如果有筛选后的数据就用筛选的,没有就用全量的 const renderData = readingStateData.filteredUsers.length > 0 ? readingStateData.filteredUsers : readingStateData.search; return ( <React.Fragment> <div className="container mt-3"> <div className="row"> <div className="col-md-3"> <div className="card"></div> </div> </div> </div> <SearchingData handleSearch={handlesearching} seardhingDTata={readingStateData.search} seardhDTata={seardhDTata} /> <table className="table table-hover text-center table-primary"> <thead className="text-black"> <tr> <th>UserName</th> <th>Phone</th> <th>Email</th> <th>Gender</th> </tr> </thead> <tbody> <React.Fragment> {/* 把原来的defaultData换成renderData即可 */} {renderData.map((user) => { return ( <tr> <td>{user.UserName}</td> <td>{user.PhoneNumber}</td> <td>{user.email}</td> <td>{user.gender}</td> </tr> ); })} </React.Fragment> </tbody> </table> </React.Fragment> ); }; export default Search;
其他可选方案
如果你不想用Redux的话,也可以用React原生的Context API实现:
- 新建一个SearchContext,在Search组件外层包裹Provider,把更新筛选数据的方法和状态存到Context里
- SearchingData组件里用useContext拿到更新方法,筛选完成后调用更新
- Search组件里用useContext拿到筛选后的数据渲染
这种方式也不需要通过父子props传值,属于公共上下文存值的方案。
内容的提问来源于stack exchange,提问作者sundeep
相关产品推荐
相关产品推荐

