ReactJs useState .map()不是函数

时间:2019-09-18 13:38:14

标签: javascript reactjs jsx

我试图了解useStateuseEffect钩子在ReactJs中的工作方式。

我收到错误消息

  

.map()不是函数

尝试在表中显示数据时。

const [posts, setPosts] = useState([]);

useEffect(() => {
    const alarmService = new AlarmService();
    const response = alarmService.getData();
    setPosts(response)
}, [])

return (
    <table className="table">
        <tbody>
        {posts.map(data => (
            <tr key={data.id}>
                <td>
                    <div className="row">
                        {data.name}
                    </div>
                </td>
                <td className="custom" >
                    <button
                        className="btn btn-danger btn-sm"
                        onClick={() => this.handleDelete(data)}
                    >
                        Delete
                    </button>
                </td>
            </tr>
        ))}
        </tbody>
    </table>
);

我认为问题出在我的useEffect中,因为我不确定该如何处理。

已解决

我研究了以下示例: https://arxiv.org/pdf/1907.04613.pdf

诀窍是在useEffect中创建一个异步函数。像这样:

useEffect(() => {
    async function test() {
       const alarmService = new AlarmService();
       const response = await alarmService.getData();
       console.log(response);
       setPosts(response)
    }
    test();
}, []);

感谢所有花时间回应和帮助的人!

2 个答案:

答案 0 :(得分:1)

我认为这里的问题是alarmService.getData是异步的,您不能正确地处理它。这就是为什么Promise待处理,并且您无法映射帖子的原因。

useEffect(() => {
    const alarmService = new AlarmService();
    alarmService.getData().then(response => response.json()).then(data =>setPosts(data))    

}, []) 

这应该可以解决您的问题。

答案 1 :(得分:0)

是的,您是对的。问题在于我们更新状态的方式,即useEffect方法。在更新状态时,setPosts不会标识这些帖子是否为数组,而是将状态更新为简单对象。因此,您会看到错误。

当我尝试在帖子中添加响应时,您可以在codeandbox中找到类似的情况 https://codesandbox.io/s/ecstatic-flower-lq2r1

请取消注释代码和框中的修复程序,以查看其是否有效。