我通过
AppContexet.Provider
向 AppContexet.Consumer
发送 usestate。我可以看到组件 - 数据到达 - 但当我尝试映射状态时,出现错误。我做错了什么?
这是家长:
import {useState} from 'react'
import Ex53Child from './Ex53Child'
import AppContexet from './Appcontext'
import React, {Component} from 'react';
const Ex53perent = ()=>
{
const [name,setName] = useState('')
const [age,setAge] = useState()
const [users,setUsers] = useState ([])
const [user,setUser] = useState ({name : '' , age : ''})
return(<AppContexet.Provider value = {{...users}}>
<div>
<h1> Ex53perent comp </h1>
Name: <input type = "text" onChange = {e=>setUser({...user ,name : e.target.value})}/><br/>
Age : <input type = "text" onChange = {e=>setUser({...user ,age : e.target.value})}/><br/>
<input type = "button" value ="Add" onClick ={e=>setUsers([...users,user])}/>
<Ex53Child/>
</div>
</AppContexet.Provider>
)
}
export default Ex53perent;
这就是孩子:
import {useState} from 'react'
import AppContexet from './Appcontext'
import Ex53GrenChild from './Ex53GrenChild'
const Ex53Child = ()=>
{
const [myUesr,setMyUser] = useState([])
return(<AppContexet.Consumer>
{
dataContext =>
(
<div>
<h1> Ex53Child comp </h1>
{
dataContext.users.map((item,index)=>
{
return<il key = {index}>
<li>{item.name}</li>
<li>{item.age}</li>
</il>
})
}
<Ex53GrenChild/>
</div>
)
}
</AppContexet.Consumer>
)
}
export default Ex53Child;
这是
appcontext
文件:
import React from 'react'
const AppContexet = React.createContext();
export default AppContexet;
单个值工作得很好,但由于某种原因我无法映射数组。
users
状态是一个数组:
const [users, setUsers] = useState([]);
您正在将数组扩展到一个对象中:
<AppContexet.Provider value={{ ...users }}>
...
</AppContexet.Provider>
这使得上下文值成为一个对象,其中数组索引现在是对象键,数组值是对象值。
您可以保持这种方式,然后您需要将上下文值转换回子级中的数组:
<AppContexet.Consumer>
{dataContext => (
<div>
<h1>Ex53Child comp</h1>
{Object.values(dataContext).map((item, index) => {
return (
<il key={index}>
<li>{item.name}</li>
<li>{item.age}</li>
</il>
);
})
}
<Ex53GrenChild/>
</div>
)}
</AppContexet.Consumer>
最好将
users
和上下文值保持为一个数组。不要将 users
状态传播到上下文值中。
<AppContexet.Provider value={{ users }}>
...
</AppContexet.Provider>
现在的上下文值是一个具有单个
users
属性的对象,即 users
状态。
<AppContexet.Consumer>
{dataContext => (
<div>
<h1>Ex53Child comp</h1>
{dataContext.users.map((item, index) => {
return (
<il key={index}>
<li>{item.name}</li>
<li>{item.age}</li>
</il>
);
})
}
<Ex53GrenChild/>
</div>
)}
</AppContexet.Consumer>
useContext
挂钩由于
Ex53Child
是一个函数组件,因此使用 AppContexet.Consumer
组件渲染函数有点愚蠢。请改用 useContext
钩子。
const Ex53Child = () => {
const [myUesr, setMyUser] = useState([]);
const { users } = useContext(AppContexet);
return (
<div>
<h1>Ex53Child comp</h1>
{users.map((item, index) => (
<il key={index}>
<li>{item.name}</li>
<li>{item.age}</li>
</il>
))}
<Ex53GrenChild />
</div>
);
}
users
作为道具传递此外,由于
Ex53perent
直接渲染 Ex53Child
,当 users
状态可以简单地作为 prop 传递时,使用上下文会带来不必要的复杂性。
const Ex53perent = () => {
const [name, setName] = useState('');
const [age, setAge] = useState();
const [users, setUsers] = useState([]);
const [user, setUser] = useState({ name: '', age: '' });
return (
<div>
<h1> Ex53perent comp </h1>
Name:{" "}
<input
type="text"
onChange={e => setUser({ ...user, name: e.target.value })}
/>
<br/>
Age:{" "}
<input
type="text"
onChange={e => setUser({ ...user, age: e.target.value })}
/>
<br/>
<input
type="button"
value="Add"
onClick={e => setUsers([...users, user])}
/>
<Ex53Child users={users} /> // <-- pass users as prop to child
</div>
);
};
...
const Ex53Child = ({ users }) => { // <-- access users from props
const [myUesr, setMyUser] = useState([]);
return (
<div>
<h1>Ex53Child comp</h1>
{users.map((item, index) => (
<il key={index}>
<li>{item.name}</li>
<li>{item.age}</li>
</il>
))}
<Ex53GrenChild />
</div>
);
}