最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use map function on react state hook - Stack Overflow

programmeradmin1浏览0评论

Can someone explain, why I cant run the JavaScript map function on a React state hook?

const [sequenceNames, setSequenceNames] = useState(null);

useEffect(() => {
  fetch('/savedFiles')
    .then(response => response.json())
    .then(data => setSequenceNames(data));
}, []);

const table = sequenceNames.map(name => Sequence(name));

This works with a for in loop, but my linter prohibits the use of for in.

const table = [];

for (const name in sequenceNames) {
  table.push(Sequence(sequenceNames[name]));
}

When I use .map though I get the following error.

TypeError: Cannot read property 'map' of null
    at main.a21158832f7ed8c55e25.bundle.js:1
    at Bi (main.a21158832f7ed8c55e25.bundle.js:1)
    at main.a21158832f7ed8c55e25.bundle.js:1
    at f (main.a21158832f7ed8c55e25.bundle.js:1)
    at d (main.a21158832f7ed8c55e25.bundle.js:1)
    at main.a21158832f7ed8c55e25.bundle.js:1

even though my sequenceNames array should not be null.

Can someone explain, why I cant run the JavaScript map function on a React state hook?

const [sequenceNames, setSequenceNames] = useState(null);

useEffect(() => {
  fetch('/savedFiles')
    .then(response => response.json())
    .then(data => setSequenceNames(data));
}, []);

const table = sequenceNames.map(name => Sequence(name));

This works with a for in loop, but my linter prohibits the use of for in.

const table = [];

for (const name in sequenceNames) {
  table.push(Sequence(sequenceNames[name]));
}

When I use .map though I get the following error.

TypeError: Cannot read property 'map' of null
    at main.a21158832f7ed8c55e25.bundle.js:1
    at Bi (main.a21158832f7ed8c55e25.bundle.js:1)
    at main.a21158832f7ed8c55e25.bundle.js:1
    at f (main.a21158832f7ed8c55e25.bundle.js:1)
    at d (main.a21158832f7ed8c55e25.bundle.js:1)
    at main.a21158832f7ed8c55e25.bundle.js:1

even though my sequenceNames array should not be null.

Share Improve this question asked Dec 1, 2018 at 9:54 Alexander HörlAlexander Hörl 6844 gold badges15 silver badges27 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

The issue you are having is that you are setting the initial state of sequenceNames null, so you are running into a race condition, where the first time you try and run a loop over sequenceNames it is null. You could initialize sequenceNames to an empty array [], but the best way to acplish what you are looking to do is by embracing hooks.

import React, { useMemo, useState } from 'react';
import { Sequence } from '.';

export interface DisplayNamesProps {
    id?: number;
}

export function DisplayNames(props: DisplayNamesProps) {
    const { id } = props;
    const [sequenceNames, setSequenceNames] = useState<Sequence[]>([]);

    // Use useEffect with the 2nd param, to guard against `fetch`
    // executing on each render. In this example I use `id` as
    // a var that should be unique for each `fetch` call.
    useEffect(() => {
        fetch(`/savedFiles/${id}`)
            .then(response => response.json())
            .then(data => setSequenceNames(data));
    }, [id]);

    // Create a memoized var `table` that updates when there
    // is a change to `sequenceNames`.
    const table = useMemo(() => {
        return sequenceNames.map(name => Sequence(name))
    }, [sequenceNames]);

    return <div>{table}</div>;
}

Change

    const table = sequenceNames.map(name => Sequence(name));

To

    const table = Array.isArray(sequenceNames) && sequenceNames.map(name => Sequence(name));
发布评论

评论列表(0)

  1. 暂无评论