Ошибка при использовании состояния и карты в reactjs

I am new to react. I am fetching github user info on search. I unable to fetch data in my child component. this is my code below. whats the problem , cant i use this.state.userList.map

class SearchHeader extends Component {
    constructor(props) {
        super(props);
        this.state = {
            errorMessage: '',
            userList: [],
            isOpen: false,
            userName:''

        };
        this.toggle = this.toggle.bind(this);
        this.getUsers = this.getUsers.bind(this);
    }
    toggle() {
        this.setState({
            isOpen: !this.state.isOpen
        });
    }
    // componentWillMount(){
    //     this.getUsers();
    //   }

      getUsers(e) {
        console.info('get users called='+e.target.value);
        fetch('https://api.github.com/search/users?q='+ e.target.value)
        .then(res => res.json())
        .then(
            userList =>{
                this.setState({userList: userList})
                console.info(userList);
            }
        );
      }


    render() {
        return (
            <div>
                <nav className = "navbar navbar-expand-lg navbar-light bg-primary  navbar-inner">
                    <div className = "collapse navbar-collapse  navbar-inner navb" >

                        <ul className = "navbar-nav  bg-light mr-auto">

                            <li className = "nav-item dropdown">
                                <a className = "nav-link dropdown-toggle auto" href = "#" id = "navbarDropdown" role = "button" data-toggle = "dropdown" aria-haspopup = "true" aria-expanded = "false">
                                    Sort
                               </a>
                                <div className = "dropdown-menu" aria-labelledby = "navbarDropdown">
                                    <a className = "dropdown-item" href = "#">Sort by Name (ascending)</a>
                                    <a className = "dropdown-item" href = "#">Sort by Name (descending)</a>
                                    <div className = "dropdown-divider"></div>
                                    <a className = "dropdown-item" href = "#">Sort by Rank (ascending)</a>
                                    <a className = "dropdown-item" href = "#">Sort by Rank (descending)</a>                                                                 
                                </div>
                            </li>
                        </ul>

                        <form className = "form-inline my-2 my-lg-0 auto" onSubmit = {this.getUsers}>
                            <div className = "form-group">
                                <input className = "form-control mr-sm-2" type = "Search" placeholder = "Search" 
                                aria-label = "Search"  
                                id = "userName"                                 
                                onKeyUp = {this.getUsers} >                 
                                </input>
                            </div>
                        </form>
                    </div>
                </nav>

                <div > 

                    <UserList userList = {this.state.userList}/>
                </div>
            </div>
        );
    }
}

export default SearchHeader;

This is my child component below where I am fetching data from parent component This is my child component below where I am fetching data from parent component

class UserList extends Component {
    constructor(props) {
        super(props)
      this.state  = {
          users:this.props.userList
      }
    }




    render() {

        return (

            <div className = "container-fluid">
                <br />
                {
                    this.state.users.map((user)=>
                    <div className = "jumbotron container">
                   {user.login}
                  </div>
                )

                }
            </div>



        );
    }
}

export default UserList;

попробуйте this.props.users.map в дочернем компоненте.

Kishan Mundha 09.06.2018 05:48

Какое сообщение об ошибке конкретный вы получаете

Jayce444 09.06.2018 05:50

Попробуйте this.props.userList или this.state.users в дочернем компоненте

Priyesh Kumar 09.06.2018 05:51

Это правильный конструктор подхода (реквизиты) {супер (реквизиты) this.state = {users: this.props.userList}}

Abhishek Konnur 09.06.2018 05:59

Вам не нужно состояние внутри компонента UserList. Попробуйте использовать карту вместо props.users. Он должен работать. Также, если оно не пришло, обновите вопрос, добавив сообщение об ошибке.

Abhishek Prakash 09.06.2018 06:06

this.props.userList не является функцией

Abhishek Konnur 09.06.2018 06:09

Я удалил состояние как компонент UserList и использовал this.props.userList.map, я получаю TypeError: this.props.userList.map не является функцией

Abhishek Konnur 09.06.2018 06:13
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
7
43
2

Ответы 2

У вас есть несколько проблем с вашими компонентами:

  • не копировать родительское состояние в детские состояния: users:this.props.userList. Используйте this.props напрямую вместо этого, и React будет знать, что он должен повторно отображать дочерние элементы.
  • не полагайтесь на текущее состояние для установки нового состояния. Используйте функцию с prevState вместо isOpen: !this.state.isOpen.
  • сделайте копию значения события перед передачей его в setState, как этот const {value} = e.target;
  • назначьте уникальный ключ каждому пользователю в вашем списке (не индексам!), иначе он не будет корректно повторно отображаться при обновлении списка

Итак, ваш код будет выглядеть так:

class SearchHeader extends Component {
    constructor(props) {
        super(props);
        this.state = {
            errorMessage: '',
            userList: [],
            isOpen: false,
            userName:''

        };
    }

    toggle = () => {
        this.setState( (prevState) => ({
            isOpen: !prevState.isOpen
        }));
    }

    getUsers = (e) => {
        const {value} = e.target;
        console.info('get users called='+value);
        fetch('https://api.github.com/search/users?q='+ value)
        ...
    }

}

а также:

class UserList extends Component {
    // Use default constructor

    render() {
        const users = this.props.userList.map( (user) => (
            <div className = "jumbotron container" key = {user.login}>
              {user.login}
            </div>
        ));
        return (
            <div className = "container-fluid">
              <br />
              {users}
            </div>
        );
    }
}

TypeError: this.props.userList.map не является функцией для этого кода в компоненте UserList

Abhishek Konnur 09.06.2018 06:19

Что отображает console.info(userList);?

RaphaMex 09.06.2018 06:24

Объект {total_count: 272740, incomplete_results: false, items: Array [30]} в консоли

Abhishek Konnur 09.06.2018 06:30

Тогда вам следует заменить this.setState({userList: userList}) на this.setState({userList: userList.items})

RaphaMex 09.06.2018 06:43

после этого setState изменится, как теперь должен выглядеть UserList

Abhishek Konnur 09.06.2018 07:01

parent component change should be.

getUsers(e) {
        console.info('get users called='+e.target.value);
        fetch('https://api.github.com/search/users?q='+ e.target.value)
        .then(res => res.json())
        .then(
            userList =>{
                this.setState({userList: userList.items})
                console.info(userList);
            }
        );
      }

Change your user list and check initially values are there or not and you dont need to user state in userList component. that is all because initially there are no values also there can be an case when you are setting state for userList value after fetching data that might be coming as null undefined or something else so put an console log there and check that too.

class UserList extends Component { оказывать() { возвращаться (
{ this.props.userList && this.props.userList.length && this.props.userList.map ((пользователь) => {Логин пользователя} )

                }
            </div>
        );
    }
}

export default UserList;

Другие вопросы по теме