Search code examples
javascriptreactjslifecycle

Cannot read property 'indexOf' of null, be expected to be react lifecycle problem


I had fetched user data from local API server, which sends JSON data, and it worked before I added searching feature. I recognized the problem that these error occurs from React's lifecycle style, but because I haven't studied about React much, so I'm asking question to solve this problem with you.

macOS Mojave, Express.js, React.js and React-Router are running my local dev server. I never tried this searching feature before.

These are my code:

UsersList.js:

import React, {Component} from 'react';
import {List, Avatar, Button, Modal, Input} from 'antd';

import UserItem from "../components/UserItem";

import blue_check from '...';

const {Search} = Input;

class UsersList extends Component {
    state = {
        users: [],
        modalVisible: false,
        dataKey: 0,
        keyword: '',
    };

    constructor(props) {
        super(props);
        this.state = {
            users: [{
                member_idx: 0,
                nickname: 'loading...',
            }]
        };
    }

    componentDidMount() {
        fetch('/api/getUsers')
            .then(res => res.json())
            .then(users => this.setState({users: users}));
    }

    showModal = (key) => {
        this.setState({
            modalVisible: true,
            dataKey: key
        });
    };

    handleClose = e => {
        console.log(e);
        this.setState({
            modalVisible: false
        });
    };

    handleSearch = (e) => {
        this.setState({
            keyword: e.target.value,
        })
    };

    render() {
        const {users, keyword} = this.state;
        const filteredUsers = users.filter(
            user => user.nickname.indexOf(keyword) !== -1
        ); // This line makes error
        return (
            <div>
                <Search
                    placeholder="Input Search Text"
                    enterButton="Search"
                    onSearch={value => this.state.handleSearch(value)}
                    size="large"
                />
                <List
                    itemLayout="horizontal"
                    dataSource={filteredUsers}
                    renderItem={item => (
                        <List.Item
                            actions={[<a onClick={() => this.showModal(item.member_idx)}>상세정보</a>, <a>이 프로필을...</a>]}>
                            <List.Item.Meta
                                style={{
                                    display: 'flex',
                                    alignItems: 'center'
                                }}
                                avatar={<Avatar src={item.image}/>}
                                title={
                                    <span>{item.nickname === null ? "<undefined>" : item.nickname} {item.blue_check === 1 &&
                                    <img src={blue_check} alt="BLUE" style={{height: '16px'}}/>
                                    }</span>}
                                description={
                                    <span><strong>{item.follow_count}</strong> Follower{item.follow_count !== 1 && "s"}</span>}
                            />
                        </List.Item>
                    )}
                />
                <Modal
                    title="상세 정보"
                    visible={this.state.modalVisible}
                    onClose={this.handleClose}
                    footer={[
                        <Button key="back" onClick={this.handleClose}>
                            닫기
                        </Button>
                    ]}
                    centered
                >
                    <UserItem dataKey={this.state.dataKey} users={this.state.users}/>
                </Modal>
            </div>
        );
    }
}

export default UsersList;

UserItem.js doesn't need in this post because it has no problem about this error.

I linked the error trace image here. Sorry about inconvenience.


Solution

  • It is possible that in your data nickname is null for one or more users and hence you should make a check for it too while filtering

         const filteredUsers = users.filter(
            user => user.nickname && user.nickname.indexOf(keyword) !== -1
        );