如何从使用状态挂钩的功能性父组件传递道具?
Posted
技术标签:
【中文标题】如何从使用状态挂钩的功能性父组件传递道具?【英文标题】:How can I pass props from a functional parent component that uses the state hook? 【发布时间】:2021-09-03 02:45:14 【问题描述】:所以我正在开发这个 UserData 应用程序(用于练习目的)。我有一个组件用于存储硬编码的用户数据——一个包含不同用户对象的数组。在我的应用程序中,我希望屏幕左侧有一个用户列表(仅显示用户名),右侧有一个面板,显示我在列表中选择的用户的所有详细信息。 (查看屏幕截图。) 我将数据导入到我的功能性父组件 AppContainer.js,我在其中使用状态挂钩将选定的用户 ID 存储在 state = 'selectedUserId' 中。我在第一次渲染时给它一个 null 值,以便在我点击任何人之前它会说“选择用户”。在我的 handleClick 函数中,我想在每次点击等时更新 userId。在我的 App.js 组件中,我想映射数据并使用不同的 li 元素以及面板呈现 ul。在此过程中,我犯了一个错误——当我点击一个用户时,会抛出一个类型错误并且控制台说“handleClick 不是一个函数”。任何想法为什么?如果您有兴趣,这里是我的沙盒列表:https://codesandbox.io/s/user-data-app-with-prop-types-tkphx?file=/src/AppContainer.js:0-571
这是 UserData.js :
export const USERS_DATA = [
id: 1,
user_name: "jwrefford0",
first_name: "Jozef",
last_name: "Wrefford",
occupation: "Editor",
catch_phrase: "repurpose next-generation schemas"
]
这是 AppContainer.js:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import useState from "react";
import USERS_DATA from "./UserData";
export default function AppContainer()
const [selectedUserId, setSelectedUserId] = useState(null);
const handleClick = (newUserId) =>
setSelectedUserId(newUserId)
;
const selectedUserObj = USERS_DATA.find(
(element) => element.id === selectedUserId
);
return (
<App selectedUserId=selectedUserId handleClick=handleClick
selectedUserObj=selectedUserObj />
)
最后是 App.js:
import "./styles.css";
import USERS_DATA from "./UserData";
export default function App(props)
const selectedUserObj = props.selectedUserObj;
const handleClick = props.handleClick;
return (
<div className="App">
<div className="list">
<ul>
USERS_DATA.map((user) => (
<li onClick=() => handleClick(user.id) key=user.id>
user.user_name
</li>
))
</ul>
</div>
<div className="panel">
<p>selectedUserObj ? `$selectedUserObj.first_name $selectedUserObj.last_name
- $selectedUserObj.occupation` : 'Select a user'</p>
<p>selectedUserObj ? `$selectedUserObj.catch_phrase` : '' </p>
</div>
</div>
);
这就是它的样子:Screenshot_UserData_App
这个任务的重点是学习如何使用不同的组件来简化每个组件的功能,以及做一个道具类型检查——我还没有做过。我发现很难掌握如何将我的应用程序的逻辑拆分为两个组件 - 当我在一个组件中创建应用程序时,它运行良好。拆分后,我造成了混乱。有人可以启发我吗?谢谢!!!
【问题讨论】:
溢出的东西对我来说很好。除了一些小的语法改进外,我觉得其他一切都很好。 感谢您的浏览!好吧,不知何故,它在控制台上说 handleClick 不是一个函数——所以每当我点击一个用户时,它都会抛出一个类型错误。对不起,我忘了说这个。如果您好奇或有带宽,这里是沙箱的链接:codesandbox.io/s/user-data-app-with-prop-types-tkphx?file=/src/… 在 index.js 中你需要传递 AppContainer 而不是 App 组件。 codesandbox.io/s/… 谢谢你,拉杰迪普! :) 哈哈,好吧,我什至没有注意到这一点。 【参考方案1】:我尝试使用您附加的代码框链接打开您的项目,但它完全崩溃了。答案很简单 - 您在默认情况下导出 App 时使用花括号导入 App。
import App from './App'; //get rid of curly braces
其余的工作正常,也许你已经解决了问题?
我要与您分享的另一件事 - 当您像这样传递句柄函数时
<li onClick=() => handleClick(user.id) key=user.id>
user.user_name
</li>
你让 React 为每个人创建特殊的功能。所以最后你在内存中有很多函数,它们几乎相同,只是有不同的 id。最好将 id 存储在您的列表项中,然后通过事件将 id 传递给您的处理函数,该事件将由捕获整个列表(in)点击的一个函数处理
function handleClick(e)
setActive(+e.target.dataset.id) // "+" here converts string value from data to number
...
<ul onClick=handleClick>
USERS_DATA.map((user) => (
<li data-id=user.id key=user.id>
user.user_name
</li>
))
</ul>
这将起作用,因为单击目标“li”将被其父组件“ul”捕获。现在您只有一个灯光功能。希望对您有所帮助。
【讨论】:
非常感谢您分享这个!确实很有帮助!我不知道我可以这样做。以上是关于如何从使用状态挂钩的功能性父组件传递道具?的主要内容,如果未能解决你的问题,请参考以下文章
我可以使用react中的useEffect挂钩从子级设置父级的状态
如何使用从 React 中的子组件获取的数据更新父组件中的状态