簡體   English   中英

為什么 map function 在我的 React 應用程序中不起作用?

[英]Why the map function doesn't work in my React app?

我正在學習 React,我想構建一個如下所示的應用程序:

在此處輸入圖像描述

基本上,用戶可以輸入他的姓名和評論並發布。 發表的評論將顯示在底部。 我正在使用 Tailwind CSS 來設置應用程序的樣式。 下面是我的代碼。

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';


class MyName extends React.Component {
    render() {
        return (<div className="rounded border border-indigo-400 m-8 p-2">
            <div className="flex flex-col items-stretch space-y-2">
                <input type="text" placeholder="Who you are?" className="border border-gray-500" value={this.state.currentUser} onChange={(e) => {
                    this.setState({currentUser: e.target.value});
                }} />
                <textarea placeholder="Say something" className="h-32 border border-gray-500" value={this.state.currentData} onChange={(e) => {
                    this.setState({currentData: e.target.value});
                }}></textarea>
                <button className="bg-green-400 text-green-100 rounded py-1 hover:bg-green-600" onClick={() => {
                    if (this.state.currentUser && this.state.currentData) {
                        this.setState({
                            comments: this.state.comments.push({
                                user: this.state.currentUser,
                                data: this.state.currentData
                            })
                        });
                        this.state.currentUser = "";
                        this.state.currentData = "";
                    }
                }}>Post comment
                </button>
            </div>
            <div className="mt-8">
                {this.comments_section()}
            </div>
        </div>);
    }

    comments_section() {
        if (this.state.comments.length == 0) {
            return <span>No Comments.</span>
        }
        else {
            console.log(Array.isArray(this.state.comments));
            console.log(this.state.comments);
            return (<ul className="space-y-4">{this.state.comments.map((item) =>
                <li className="flex items-start space-x-2" key={item.user + item.data}>
                    <div className="flex flex-col items-start space-y-1">
                        <img className="rounded-full" src="http://placekitten.com/50/50" />
                        <span className="text-xs text-gray-500">{item.user}</span>
                    </div>
                    <span>{item.data}</span>
                </li>)}
            </ul>)
        }
    }

    constructor() {
        super();

        this.state = {
            currentUser: "",
            currentData: "",
            comments: [{
                user: "User One",
                data: "Hi, hello world!"
            }, {
                user: "User Two",
                data: "Hi, hello world!"
            }]
        }
    }
}

ReactDOM.render(
    <MyName />,
    document.getElementById('root')
);

reportWebVitals();

問題是,當我在輸入中鍵入內容並單擊按鈕時,它會出錯並指出this.state.comments.map不是 function。 我添加了一些console.log語句來調試它,發現起初this.state.comments是一個數組。 但是一旦我點擊了按鈕,它就不是了。 如何解決這個問題? 謝謝。

this.setState({
   comments: this.state.comments.push({
     user: this.state.currentUser,
     data: this.state.currentData
   })
});

array.push 返回一個數字,即數組的長度。 因此,您將 state.comments 設置為一個數字,而數字沒有 map 方法。

您不應該為此使用 push,因為它會改變數組,並且 react 要求您的 state 是不可變的。 此外,您有幾行手動設置 this.state.currentUser 和 this.state.currentData。 對 state 的更改應始終通過設置 state,而不是手動修改 this.state。

const newComments = [...this.state.comments, {
  user: this.state.currentUser,
  data: this.state.currentData
}]
this.setState({ 
  comments: newComments,
  currentUser: "",
  currentData: ""
});

另一個改進:由於您將新的 state 基於舊的 state,因此您應該使用 setState 的 function 版本。 React 將向您傳遞最新版本的 state,這消除了您使用過時版本的 state 的可能性(您的代碼可能無法遇到此錯誤,但它可能發生在更復雜的情況下,所以它是好習慣)

this.setState(prev => {
  const newComments = [...prev.comments, {
    user: prev.currentUser,
    data: prev.currentData
  }]
  return { 
    comments: newComments
    currentUser: "",
    currentData: ""
  };
});

array.push返回一個數字,即數組的長度,因此您基本上是在將注釋設置為其長度。

if (this.state.currentUser && this.state.currentData) {
  let { comments, currentUser, currentData } = this.state;
    comments.push({
     user: currentUser,
     data: currentData
    })
 this.setState({comments, currentUser : "", currentData: "" })
}

我不是反應專家,但我認為您需要像這樣從 map 返回您的 jsx:

<ul className="space-y-4">
{this.state.comments.map((item) => return (
                <li className="flex items-start space-x-2" key={item.user + item.data}>
                    <div className="flex flex-col items-start space-y-1">
                        <img className="rounded-full" src="http://placekitten.com/50/50" />
                        <span className="text-xs text-gray-500">{item.user}</span>
                    </div>
                    <span>{item.data}</span>
                </li>))}
            </ul>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM