Прикрепить вложенный компонент к поставщику контекста с возможностью изменения контекста - PullRequest
1 голос
/ 21 февраля 2020

Я пытаюсь перебрать массив объектов, но он не выдает ошибку. У меня есть 3 файла, из которых я пытаюсь извлечь данные, я не так хорош в массивах и обходе объектов, а также нов в реагирующем контекстеAPI, поэтому некоторые советы и рекомендации будут оценены.

Это userContext. js file:

import React, { useState, createContext } from 'react';

export const UserContext = createContext();
export const UserProvider = props => {
var [users, setUsers] = useState([
    {
        "users": [
            {
                id: '1',
                name: 'user1'
            },
            {
                id: '2',
                name: 'user2'
            },
            {
                id: '3',
                name: 'user3'
            },
            {
                id: '4',
                name: 'user4'
            },
        ],
        "todos": [
            {
                "userId": 1,
                "id": 1,
                "title": "delectus aut autem",
                "completed": false
            },
            {
                "userId": 1,
                "id": 2,
                "title": "quis ut nam facilis et officia qui",
                "completed": false
            },
            {
                "userId": 2,
                "id": 1,
                "title": "fugiat veniam minus",
                "completed": false
            },
            {
                "userId": 2,
                "id": 2,
                "title": "et porro tempora",
                "completed": true
            },
        ]
    }

]);
return (
<UserContext.Provider value={[users, setUsers]}>
    {props.children}
</UserContext.Provider>
);
}

Это userList. js file:

import React, {useState, useContext} from 'react';
import {Form} from 'react-bootstrap'
import User from './User'
import {UserContext} from './UserContext'


const UserList = () => {

const [users, setUsers] = useContext(UserContext);
return(
    <Form.Group controlId="exampleForm.ControlSelect1">
    <Form.Label>Please select a user</Form.Label>
    <Form.Control as="select" onChange={()=> {this.changeUser()}}>
        {
            Object.keys(users).map(fst =>{
                users[fst].map(sub_fst => 
                    {
                    <User name={sub_fst.name} key={sub_fst.id} />
                }

                );
            })
        }
    </Form.Control>
</Form.Group>
);
}
export default UserList;

И здесь я хочу, чтобы данные отображались в User. js:

import React from 'react';

const User = (props) => {
return (

    <option>

        {props.name}

    </option>

);

}
export default User;

Ценю любую помощь и исправления.

1 Ответ

1 голос
/ 21 февраля 2020

Мне кажется, что вы в некоторой степени перепутались с синтаксисом, поэтому при незначительном рефакторинге ваш код будет работать так:

const { useState, useContext, useEffect, createContext } = React,
      { render } = ReactDOM,
      { Form } = ReactBootstrap

const defaultState = {"users":[{id:'1',name:'user1'},{id:'2',name:'user2'},{id:'3',name:'user3'},{id:'4',name:'user4'},],"todos":[{"userId":1,"id":1,"title":"delectus aut autem","completed":false},{"userId":1,"title":"quis ut nam facilis et officia qui","completed":false},{"userId":2,"id":1,"title":"fugiat veniam minus","completed":false},{"userId":2,"id":2,"title":"et porro tempora","completed":true}], currentUserId: null, setCurrentUserId: () => {}},
      UserContext = createContext(defaultState)
      

const UserProvider = ({children}) => {
  const [state, setState ] = useState({
      ...defaultState,
      setCurrentUserId: userId => setState({...state, currentUserId:userId})
  })
        
  return (
      <UserContext.Provider value={state} >
        {children}
      </UserContext.Provider>
  )
}


const User = ({name,value}) => <option {...{value}}>{name}</option>

const UserList = () => {

const  {users, currentUserId, setCurrentUserId} = useContext(UserContext)

return (
      <Form.Group controlId="exampleForm.ControlSelect1">
      <Form.Label>Please select a user {currentUserId && `(current user is ${users.find(({id}) => id == currentUserId).name})`}</Form.Label>
      <Form.Control as="select" onChange={({target:{value}}) => setCurrentUserId(value)}>
          {
              [{},...users].map(({id,name}) => <User {...{name, key: id, value: id}} />)
          }
      </Form.Control>
  </Form.Group>
 )
}


render (
  <UserProvider>
    <UserList />
  </UserProvider>,
  document.getElementById('root')
)
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" /><script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script><script src="https://unpkg.com/react-bootstrap@next/dist/react-bootstrap.min.js"></script><div id="root"></div>
...