简体   繁体   English

NextJS - 未处理的运行时错误类型错误:将 class function 转换为挂钩 function 时无法读取未定义的属性(读取“长度”)

[英]NextJS - Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'length') when converting a class function to hook function

I'm trying to convert a class function file to hook function but am getting the following error whenever entering text in the field.我正在尝试将 class function 文件转换为挂钩 function 但每当在字段中输入文本时都会收到以下错误。

Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'length')未处理的运行时错误类型错误:无法读取未定义的属性(读取“长度”)

I think I've converted everything but just can't find what - am I missing something?我想我已经转换了所有东西,但找不到什么 - 我错过了什么吗?

New hooks code with the above error:带有上述错误的新钩子代码:

import React, { useState } from "react";

function Todo(props) {
    const [state, setState] = useState({ items: [], text: "" });

    const handleChange = (e) => {
        setState({ text: e.target.value });
    };

    const handleSubmit = (e) => {
        e.preventDefault();

        if (state.text.length === 0) {
            return;
        }

        const newItem = {
            text: state.text,
            id: Date.now(),
        };

        setState((state) => ({
            items: state.items.concat(newItem),
            text: "",
        }));
    };

    return (
        <div>
            <form onSubmit={handleSubmit}>
                <label htmlFor="new-todo">What needs to be done?</label>
                <input id="new-todo" onChange={handleChange} value={state.text} />
                <button>Add #{state.items.length + 1}</button>
            </form>
            <TodoList items={state.items} />
        </div>
    );
}

function TodoList(props) {
    return (
        <ul>
            {props.items.map((item) => (
                <li key={item.id}>{item.text}</li>
            ))}
        </ul>
    );
}

export default Todo;

Previous class functions file being converted to hooks file above:以前的 class 函数文件被转换为上面的钩子文件:

import React from "react";

class Todo extends React.Component {
    constructor(props) {
        super(props);
        this.state = { items: [], text: "" };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    render() {
        return (
            <div>
                <form onSubmit={this.handleSubmit}>
                    <label htmlFor="new-todo">What needs to be done?</label>
                    <input
                        id="new-todo"
                        onChange={this.handleChange}
                        value={this.state.text}
                    />
                    <button>Add #{this.state.items.length + 1}</button>
                </form>
                <TodoList items={this.state.items} />
            </div>
        );
    }

    handleChange(e) {
        this.setState({ text: e.target.value });
    }

    handleSubmit(e) {
        e.preventDefault();
        if (this.state.text.length === 0) {
            return;
        }
        const newItem = {
            text: this.state.text,
            id: Date.now(),
        };
        this.setState((state) => ({
            items: state.items.concat(newItem),
            text: "",
        }));
    }
}

class TodoList extends React.Component {
    render() {
        return (
            <ul>
                {this.props.items.map((item) => (
                    <li key={item.id}>{item.text}</li>
                ))}
            </ul>
        );
    }
}

export default Todo;

Many thanks!非常感谢!

It happens because in handleChange u rewrite whole state with { text: e.target.value } (state hook works differently than class based component state) You should try this:发生这种情况是因为在 handleChange 中你用 { text: e.target.value } 重写整个 state (状态挂钩的工作方式与基于 class 的组件状态不同)你应该试试这个:

const handleChange = (e) => {
    setState((prevState) => {...prevState, text: e.target.value });
};

The issue is most likely due to this block of code.该问题很可能是由于此代码块造成的。

    const handleChange = (e) => {
        setState({ text: e.target.value });
        // mutating state as this will overwite the current values with
        // {text: e.target.value }
    };

a better way of doing this could be to use the rest syntax like this.更好的方法是使用 rest 语法,如下所示。

    const handleChange = (e) => {
        setState((prev) => { return {...prev, [text]: e.target.value }});
        // and now when you update text, it shouldnt overwrite your items or 
        //vice versa
    };

If I had to convert, then I would do it this way.如果我必须转换,那么我会这样做。

import React, { useState } from "react";

const Todo = () => {
  const [items, setItems] = useState([]);
  const [text, setText] = useState("");

  const handleChange = (e) => {
    setText(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    if (text.length === 0) {
      return;
    }
    const newItem = {
      text,
      id: Date.now()
    };
    setItems((prevItems) => [...prevItems, newItem]);
    // clear the input box after adding.
    setText("");
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <label htmlFor="new-todo">What needs to be done?</label>
        <input id="new-todo" onChange={handleChange} value={text} />
        <button>Add #{items.length + 1}</button>
      </form>
      <TodoList items={items} />
    </div>
  );
};

const TodoList = (props) => {
  const { items } = props;

  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>{item.text}</li>
      ))}
    </ul>
  );
};

export default Todo;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 未处理的运行时错误类型错误:无法读取未定义的属性(读取“长度”) - Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'length') 未处理的运行时错误 =&gt; TypeError:无法读取未定义的属性(读取“setState”) - Unhandled Runtime Error => TypeError: Cannot read properties of undefined (reading 'setState') 未处理的运行时错误 nextjs - TypeError:无法读取 null 的属性(读取“tagName”) - Unhandled Runtime Error nextjs - TypeError: Cannot read properties of null (reading 'tagName') 未处理的拒绝 (TypeError):无法读取未定义的属性(读取“长度”) - Unhandled Rejection (TypeError): Cannot read properties of undefined (reading 'length') Next.js 错误“未处理的运行时错误类型错误:无法读取未定义的属性(读取&#39;scrollTo&#39;)” - Next.js error "Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'scrollTo')" 未处理的运行时错误类型错误:当我尝试使用 next.js 的图像组件时无法读取未定义的属性(读取“调用”) - Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'call') when I try to use the Image component of next.js TypeError: Cannot read properties of null (reading 'length') in Nextjs 错误 - TypeError: Cannot read properties of null (reading 'length') in Nextjs error 未处理的运行时错误 | TypeError:无法读取 null 的属性(读取“CodeMirror”) - Unhandled Runtime Error | TypeError: Cannot read properties of null (reading 'CodeMirror') 未处理的拒绝 (TypeError):无法读取未定义的属性(读取“错误”) - Unhandled Rejection (TypeError): Cannot read properties of undefined (reading 'error') 反应:未处理的拒绝(TypeError):无法读取未定义的属性(读取“错误”) - React : Unhandled Rejection (TypeError): Cannot read properties of undefined (reading 'error')
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM