1.首先
我
“React 在文件之间来回走,我不懂!”
“反应太难了”
... 所以我认为。
我写这篇文章是为了组织这个来回的 React 流程。
如果您能帮助有相同想法的人,我将不胜感激。
在本文中,我们将研究“状态管理”。
国家的极好的是基本内容。
* 对于状态管理,不使用useState 以外的钩子和库。
极好的我想看看 state 的值是如何通过简单的内容传递的。
如果您能指出我是否误解了某些内容,我将不胜感激。
2. 内容
1.首先
2. 内容
3.你可以从这篇文章中学到什么
4.环境
5.状态管理
5.1.从上到下传递状态值
5.2.自下而上传递状态值
六,结论
7. 参考
3.你可以从这篇文章中学到什么
状态的值为
- 父组件→子组件→孙子组件(从上到下传递状态值)
- 孙组件→子组件→父组件(从下往上传递状态值)
我会看流量。
接收根组件中的状态值,将值传递给父/子/孙子组件,显示用户信息,
单击孙组件的删除按钮,并将更改的状态值传递给子/父组件。
↓ 就是这样一个简单的应用程序。
最终的源代码如下。
本文不包括用于类型定义的src/user.ts 和src/userList.ts 以及用于用户信息的src/user-data.json。
另外,src/index.tsx是显示组件的文件,这里也省略说明。
关于上面的源代码,如果你能看到这样的定义,我将不胜感激。
(如果您复制以下内容,它将起作用。)
export type User = {
id: string;
name: string;
age: number;
onRemoveUser?: (id: string) => void;
onRemove?: (id: string) => void;
};
import type { User } from "./user";
export type UserList = {
users: User[];
onRemoveUser?: (id: string) => void;
};
[
{
"id": "dahis1",
"name": "daishi",
"age": 10
},
{
"id": "manju2",
"name": "manju",
"age": 20
},
{
"id": "daishiman3",
"name": "daishiman",
"age": 30
}
]
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
import { useState } from "react";
import userData from "./user-data.json";
import { UserList } from "./UserList";
import type { User } from "./user";
export default function App() {
const [users, setUsers] = useState<User[]>(userData);
const removeUser = (id: string) => {
const newUsers = users.filter((user) => user.id !== id);
setUsers(newUsers);
};
return (
<div>
<UserList users={users} onRemoveUser={removeUser} />
</div>
);
}
import { FC } from "react";
import { User } from "./User";
import type { UserList as UserListType } from "./userList";
export const UserList: FC<UserListType> = ({
users = [],
onRemoveUser = (f) => f
}) => {
if (!users.length) return <div>表示できるユーザーはいません</div>;
return (
<div>
{users.map((user) => (
<User key={user.id} {...user} onRemove={onRemoveUser} />
))}
</div>
);
};
import { FC } from "react";
import type { User as UserType } from "./user";
export const User: FC<UserType> = ({
id,
name,
age,
onRemove = (f) => f
}) => {
return (
<section>
<p>
{name}(年齢:{age}歳)
</p>
<button onClick={() => onRemove(id)}>削除</button>
</section>
);
};
4.环境
- 反应:17.0.2
- 打字稿:4.4.2
5.状态管理
我们将看一个管理状态值、显示用户信息和删除它们的简单流程。
-
父母组件 →孩子组件 →孙子零件
(从上到下传递状态值) -
孙子组件 →孩子组件 →父母零件
(从下到上传递状态值)
我会在流程中查看它。
1.父母组件 →孩子组件 →孙子组件(从上到下传递状态值)
现在,将 src/user-data.json 用户信息从父 (App) 组件传递给孙 (User) 组件并显示用户信息。
2.孙子组件 →孩子组件 →父母组件(从下到上传递状态值)
现在,点击孙子(User)组件的删除按钮,减少显示的状态值的用户信息。
观察这些趋势状态值来回走动我想确认
5.1.从上到下传递状态值
我们先来看看从顶部(父)到底部(孙)传递状态值的流程。
本次使用的源码结构如下。
- 父组件:
src/App.tsx - 子组件:
src/UserList.tsx - 孙子组件:
src/User.tsx
5.1.1. 父组件向子组件传递状态值
首先,让我们看一下父 (App) 组件。
import { useState } from "react";
import userData from "./user-data.json";
import { UserList } from "./UserList";
import type { User } from "./user";
export default function App() {
const [users] = useState<User[]>(userData);
return (
<div>
<UserList users={users} />
</div>
);
}
App组件配置
- 使用
useState管理状态 - 将状态管理值 (
users) 传递给UserList组件 -
显示
UserLIst它已成为。
让我们仔细看看。
1.用
useState进行状态管理使用
useState钩子管理状态值。(↓
useState的参考文章)变成以下部分。
const [users] = useState<User[]>(userData);由于我们还没有更新值,所以我们还没有编写更新的函数。
将
src/user-data.json的userData赋值给变量users作为初始值。2.将状态管理值(
users)传递给子组件您正在将变量
users的值传递给子 (UserList) 组件的users属性。<UserList users={users} />上面的
UserList组件定义在以下子 (UserList) 组件中完成:3.显示
UserLIstsrc/App.tsx显示UserList组件。这是传递父 (
App) 组件的状态值的流程。5.1.2. 将状态值从子组件传递给孙子组件
然后将从父 (
App) 组件接收到的状态值传递给孙 (User) 组件子 (UserList) 组件我会看看这次是
App.tsx使用UserList组件,
正如“组件”一词所暗示的那样,UserList组件可以在各个地方使用。这就是组件有用的原因。
让我们回过头来看看源代码。
src/UserList.tsx(子组件)import { FC } from "react"; import { User } from "./User"; import type { UserList as UserListType } from "./userList"; export const UserList: FC<UserListType> = ({ users = [], }) => { if (!users.length) return <div>表示できるユーザーはいません</div>; return ( <div> {users.map((user) => ( <User key={user.id} {...user} /> ))} </div> ); };UserList组件由以下部分组成:-
UserList是用箭头函数写的(关于箭头函数的参考文章) - 参数
users = []省略users: users = [] -
users.length为假时的返回值 (0) -
users.length不为假时的返回值 (0)1.
UserList写成箭头函数起初它可能看起来令人困惑,但将其分解,您会发现它使用箭头函数。
const const UserList: FC<UserListType> = () => {}UserLIst组件使用这个↑。2.
users = []在参数中省略users: users = []users在UserList的箭头函数参数中省略了users: users。 (参考文章)
因此,users的值被分配给users属性。users的值为天空[]默认被替换。把这些放在一起,
users = []与users: users = []相同,并使用缩写符号编写。3.
users.length为假时的返回值(0)if (!users.length) return <div>表示できるユーザーはいません</div>;如您所见,当
users.length为假(0)时,<div>表示できるユーザーはいません</div>;它显示出来。
4.
users.length不为假时的返回值(0)当
users.length不为假(0)时,<div> {users.map((user) => ( <User key={user.id} {...user} /> ))} </div>过程将起作用。
users数组通过map函数转换为User组件数组并显示。{...user}将user.name和user.age组合在一起,而不是user.id并将它们传递给孙子 (User) 组件。5.1.3. 在孙子组件中接收状态值
最后,我们将看看孙子 (
User) 组件。状态值从父级(
App)传递给子级(UserList)和孙级(User),
它是如何显示最后传递的值的一个组件。src/User.tsx(孙组件)import { FC } from "react"; import type { User as UserType } from "./user"; export const User: FC<UserType> = ({ name, age, }) => { return ( <section> <p> {name}(年齢:{age}歳) </p> </section> ); };User组件配置-
UserList是用箭头函数写的(关于箭头函数的参考文章) - 参数
name和age省略name: name和age: age - 显示姓名和年龄
它已成为。
1.
UserList写成箭头函数由于和之前的内容相同,我们省略了细节。
const User: FC<UserType> = () => {};就是它。
2.参数
name和age省略name: name和age: age由于这里相同,所以省略说明。
-
name是name: name的缩写 -
yera是yera: age的缩写
3.显示姓名和年龄
从父组件按顺序传过来的状态值最终显示在这里。
return ( <section> <p> {name}(年齢:{age}歳) </p> </section> );路很长,
我希望你已经掌握了从父(App)组件到孙(User)组件的传递和显示状态值的流程。接下来,我们看一下在孙(
User)组件上定义删除按钮并将要删除的状态值传递给父(App)组件的流程。5.2.从下往上传递状态值
该实现的概要如下。
- 在孙子组件中定义删除按钮
- 将已删除的状态值传播到父组件
- 更新父组件中的状态
- 之后,流程和上面传状态值一样
现在让我们将它添加到孙子组件中。
5.2.1. 孙子组件增加删除功能
向孙 (
User) 组件添加删除功能。我们在这里做的是
点击查看发生了哪个用户的事件(删除)子 (UserList) 组件是告诉src/User.tsx(孙组件)import { FC } from "react"; import type { User as UserType } from "./user"; export const User: FC<UserType> = ({ + id, name, age, + onRemove = (f) => f }) => { return ( <section> <p> {name}(年齢:{age}歳) </p> + <button onClick={() => onRemove(id)}>削除</button> </section> ); };让我们看看流程。
- 删除按钮点击事件被触发
- 调用
onRemove函数删除 -
onRemove函数是添加到User组件的新属性 -
onRemove函数在参数中接收id值(知道哪个用户) -
onRemove函数接受id并返回id - 使用孙 (
User) 组件将id返回给子 (UserList) 组件这就是您将状态值从孙 (
User) 组件传递给子 (UserList) 组件的方式。5.2.2.子组件增加删除功能
接下来,添加逻辑以将
id从孙 (User) 组件传播到父 (App) 组件。孙子 (
User) 组件执行id传递到这里。src/UserList.tsx(子组件)import { FC } from "react"; import { User } from "./User"; import type { UserList as UserListType } from "./userList"; export const UserList: FC<UserListType> = ({ users = [], + onRemoveUser = (f) => f }) => { if (!users.length) return <div>表示できるユーザーはいません</div>; return ( <div> {users.map((user) => ( - <User key={user.id} {...user} /> + <User key={user.id} {...user} onRemove={onRemoveUser} /> ))} </div> ); };让我们看看情况如何。
- 从孙 (
User) 组件接收id作为onRemove属性的值 -
id在 1 中收到。分配给onRemoveUser函数 -
onRemoveUser函数是添加到UserList组件的新属性 -
分配给
onRemoveUser函数的onRemoveUserid按原样返回id - 使用子 (
UserList) 组件将id返回给父 (App) 组件流程几乎与我对孙子 (
User) 组件所做的相同。5.2.3. 父组件添加删除功能
最后,向父 (
App) 组件添加删除功能。这里我们需要添加逻辑来更新从子(
UserList)传递给父(App)的状态值。src/App.tsx(父组件)import { useState } from "react"; import userData from "./user-data.json"; import { UserList } from "./UserList"; import type { User } from "./user"; export default function App() { - const [users] = useState<User[]>(userData); + const [users, setUsers] = useState<User[]>(userData); + const removeUser = (id: string) => { + const newUsers = users.filter((user) => user.id !== id); + setUsers(newUsers); + }; return ( <div> - <UserList users={users} /> + <UserList users={users} onRemoveUser={removeUser} /> </div> ); }我们来看看最终的流程。
-
在
useState钩子中添加setUser变量以更新users - 从子 (
UserList) 组件接收id作为onRemoveUser属性的值 -
id在 1 中收到。分配给removeUser函数 -
removeUser函数是
4.1. 使用filter函数从users数组中提取user.id与id不匹配的用户
4.2. 将4.1.中提取的用户赋值给newUsers变量
4.3. 将newUsers传递给setUsers以更新状态值 -
users更新为再次从上到下传递状态值 - 下面重复“从上到下传递状态值”
变成。
最后一个父级 (
App) 可能看起来有点复杂,但这就是我们使用useState挂钩来管理状态值的方式。但是,由于状态值是像桶旅一样传递的,所以组件的层数越多,就越复杂。
我想写另一篇关于解决这些问题的钩子和库的文章。
六,结论
状态值
- 父组件→子组件→孙子组件(从上到下传递状态值)
- 孙组件→子组件→父组件(从下往上传递状态值)
通过查看传递的流程,我能够掌握 React 的重要状态管理。
但是,我觉得一个个通过状态很麻烦。
这一次,是从父母到孙子,但如果层数多了,就会变得难以管理。
出于这个原因,我认为创建了方便的钩子和库......
未来,我想赶上状态管理钩子和库,成为 React 大师。
感谢您阅读到最后?
如果您也可以阅读其他文章,我会很高兴?♂️
7. 参考
- 开发 React 动手学习 Web 应用程序的最佳实践
作者:亚历克斯·班克斯、伊芙·波切洛
翻译:宫崎骏 - [JavaScript] 对象字面量的简写符号
-
在
- 从孙 (
-
-
-
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308631506.html