React.js 未捕获到小写字母 () 函数的键入错误

React.js uncaught Typing error tolowercase() function

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

    import React from 'react';
    import axios from 'axios';
    import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
    import SearchBar from './component/SearchBar';
    import UserList from './component/UserList';
    import AddUser from './component/AddUser';





    class App extends React.Component {

        state = {
            users: [

            ],
            searchQuery: ""
        }

        async componentDidMount() {
            this.getUsers();
         }

         async getUsers() {
            const response = await axios.get("http://localhost:3004/users");
            //console.log(response);
            this.setState({ users: response.data })
        }



        deleteUser = async (user) => {
            axios.delete(`http://localhost:3004/users/${user.id}`)
            const newUserList = this.state.users.filter(
                m => m.id !== user.id
            )


            this.setState(state => ({
                users: newUserList
            }))

        }


        searchUser = (event) => {
           
            this.setState({ searchQuery: event.target.value })
        }



        addUser = async (user) => {
            await axios.post(`http://localhost:3004/users/`, user)

            this.setState(state => ({
                users:state.users.concat([user])
            }))
            this.getUsers();
        }

        render() {

            let filteredUsers = this.state.users.filter(
                (user) => {
                    return user.name.toLowerCase().indexOf(this.state.searchQuery.toLowerCase()) !== -1
                }
            ).sort( (a, b) => {
                return a.id < b.id ? 1 : a.id > b.id ? -1 : 0;
            });

            return (
                <Router>

                    <div className="container">
                        <Switch>  
                            <Route path="/" exact render={() => (

                            <React.Fragment>

                                <div className="row">
                                    <div className="col">
                                        <SearchBar searchUserProp={this.searchUser} />

                                        <UserList
                                            users={filteredUsers}
                                            deleteUserProp={this.deleteUser}
                                        />
                                    </div>
                                </div>

                            </React.Fragment>

                        )} > </Route>

                            <Route path="/add" render={({history}) => (
                            
                            
                            <AddUser 
                            onAddUser = {(user) => {this.addUser(user)
                            history.push("/")}}
                            />)} /> 
                            
                            </Switch>

                    </div>

                </Router>
            )

        }

    }

    export default App;

在我添加编辑组件之前它一直没有问题。我正在学习,我不知道我错在哪里。它说 tolowercase() 函数但是当我完全删除它们时,出现空屏幕。我想这没有关系。我犯过一次这个错误,但我现在解决了它现在太不一样了。

如果您的用户数组为空,则 user.name 将未定义,并且 user.name.toLowerCase() 将抛出错误。

所以你可以通过添加 ?问号。

user?.name?.toLowerCase()?.indexOf(this.state.searchQuery?.toLowerCase()) !== -1

最终代码可以是这样的

let filteredUsers = this.state.users.filter(
            (user) => user?.name?.toLowerCase()?.indexOf(this.state.searchQuery?.toLowerCase()) !== -1 )

filteredUsers = filteredUsers.length > 1 ? filteredUsers.sort( (a, b) => {
            return a.id < b.id ? 1 : a.id > b.id ? -1 : 0;
        }) : filteredUsers //only sort if more than 1

此问题的一个解决方案是使用简单的 if 语句或 ternary 运算符包装所有使用 user 对象的代码。你想要这样做的原因是,如果 user 对象开始时没有默认值,它被认为是一个空对象,所以使用 user.name 将是未定义的,你可能已经注意到了,因为你正在一个错误。

深入研究 React,您会注意到 componentDidMount 运行 组件安装到 DOM 之后(您正在正确的位置获取数据! !)。这意味着 render 函数中的所有代码将在您填充 user 对象之前 运行,这就是您收到错误的原因。因此,为了解决这个问题,您可以按照以下步骤操作:

// Start of the ternary operator.
// If the user object is not empty, the code after the '?' and before the ':' will
// be executed. If the object is empty, then 'null' will be returned causing you 
// to not be given an error.
user ? 
 let filteredUsers = this.state.users.filter((user) => {
    return ( 
        user.name.toLowerCase().indexOf(this.state.searchQuery.toLowerCase()) !== -1
      )}
      ).sort( (a, b) => {
         return a.id < b.id ? 1 : a.id > b.id ? -1 : 0;
 })
: null
// You can replace null with any value that you like, or you can keep it null.

所以,为了总结这个答案,如果您想使用您知道可能并不总是被定义的数据,请使用三元运算符或 if 语句将您使用数据的地方包装起来。

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

import React from 'react';
import axios from 'axios';
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import SearchBar from './component/SearchBar';
import UserList from './component/UserList';
import AddUser from './component/AddUser';
import EditUser from './component/EditUser';

class App extends React.Component {

    state = {
        users: [],
        searchQuery: ""
    }

    async componentDidMount() {
        this.getMovies();
    }

    async getMovies() {
        const response = await axios.get("http://localhost:3004/users");
        this.setState({ users: response.data });
    }

    deleteUser = async (user) => {
        axios.delete(`http://localhost:3004/users/${user.id}`)
        const newUserList = this.state.users.filter(
            m => m.id !== user.id
        )
        this.setState(state => ({
            users: newUserList
        }))
    }

    searchUser = (event) => {
        this.setState({ searchQuery: event.target.value })
    }

    addUser = async (user) => {
        await axios.post(`http://localhost:3004/users/`, user)
        this.setState(state => ({
            users: state.users.concat([user])
        }))
        this.getMovies();
    }

    editUser = async (id, updatedUser) => {
        await axios.put(`http://localhost:3004/users/${id}`, updatedUser)
        this.setState(state => ({
            users: state.users.concat([updatedUser])
        }))
        this.getMovies();
    }

    render() {

        let filteredUsers = this.state.users.filter(
            (user) => {
                return user.name.toLowerCase().indexOf(this.state.searchQuery.toLowerCase()) !== -1
            }
        ).sort((a, b) => {
            return a.id < b.id ? 1 : a.id > b.id ? -1 : 0;
        });

        return (
            <Router>
                <div className="container">
                    <Switch>
                        <Route path="/" exact>
                            <div className="row">
                                <div className="col">
                                    <SearchBar searchUserProp={this.searchUser} />
                                    <UserList
                                        users={filteredUsers}
                                        deleteUserProp={this.deleteUser}
                                    />
                                </div>
                            </div>
                        </Route>
                        <Route path="/add" render={({ history }) => (
                            <AddUser onAddUser={(user) => {
                                this.addUser(user)
                                history.push("/")
                            }} />
                        )} />
                        <Route path="/edit/:id" exact render={(props) => (
                            <EditUser
                                {...props}
                                onEditUser={(id, user) => {
                                    this.editUser(id, user)
                                }
                                }
                            />
                        )} />
                    </Switch>
                </div>

            </Router>
        )
    }
}
export default App;

我解决了这个问题。问题是,当我提交空的添加表单时,json 文件已损坏。我编辑了 json 文件,并改进了代码,通过在 componentdidmount 中添加 getdata 函数来同时获取准确的数据。