我无法从 AppContextet.Consumer 映射 usestate

问题描述 投票:0回答:1

我通过

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;

单个值工作得很好,但由于某种原因我无法映射数组。

reactjs react-hooks react-context
1个回答
0
投票

问题

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>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.