【问题标题】:React & Objects - TypeError: Cannot read property 'map' of undefined反应和对象 - 类型错误:无法读取未定义的属性“地图”
【发布时间】:2021-05-22 20:46:03
【问题描述】:

我正在尝试从 django 数据库中检索对象(电机)列表并将其存储在我的 MachineTemplate 组件的状态中。

这是组件

export default class MachineTemplate extends Component {
    constructor(props) {
        super(props);
                this.state = {
            myName: this.props.match.params.id,
            motors: {},
            error: "None",
            loaded: false
        }
        
        this.getMachineDetails = this.getMachineDetails.bind(this);
    }

    componentDidMount() {
        this.getMachineDetails();
    }

    getMachineDetails = () => {
        const requestOptions = {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
            name: this.state.myName,
            }),
        };

        fetch("http://127.0.0.1:8000/get-motors", requestOptions)
        .then((response) => {
            if (response.ok) {
                this.setState({ motors: response.data });
            } else {
                this.setState({ error: "Motors not found." });
            }
        })
        .catch((error) => {
            console.log(error);
        });
        this.setState({loaded: true});
    }

    render() {
        if (this.state.loaded) {
            return (
                <div>
                    <h1>{this.state.name}</h1>
                    <h3>{this.state.error}</h3>
                    {this.state.motors.map(motor => {
                        return <Button key = {motor.number}>{motor.number}</Button>
                    })}
                </div>
            )
        } else {
            return(
                <div>
                    <h1>Awaiting machine details...</h1>
                </div>
            )
        }
    }

}

这是我得到的错误 TypeError: Cannot read property 'map' of undefined

我可以确认 fetch 正确返回了我需要的电机对象列表,这些对象在响应中的格式如下: 0: {number: 0, enabled: true, item: "EMPTY", machine: 48}

我能够通过不同组件中的简单名称列表使这个精确的设置正常工作,因此我们将不胜感激。

【问题讨论】:

标签: reactjs jsx


【解决方案1】:

fetch()异步的。这意味着你不能依赖它在下一条语句之前完成它的执行:

fetch(/**/);
// ...
this.setState({loaded: true}) // fetch() might not finish executing when this statement is executed

因此,您必须确保将 loaded 状态变量设置在正确的位置。查看您的代码,这样的事情应该可以工作:

    fetch("http://127.0.0.1:8000/get-motors", requestOptions)
    .then((response) => {
        if (response.ok) {
            this.setState({
                motors: response.json(), // As suggested by @buzatto
                loaded: true
            });
        } else {
            this.setState({ error: "Motors not found." });
        }
    })
    .catch((error) => {
        console.log(error);
    });

获取每个道具更改

考虑添加 componentDidUpdate 以使用有关道具更改的新数据重新获取和重新渲染您的组件:

componentDidUpdate(prevProps) {
  // Typical usage (don't forget to compare props):
  if (this.props.match.params.id !== prevProps.props.match.params.id) {
    this.setState({loaded: false}) 
    this.getMachineDetails();
  }
}

还可以查看useEffect 钩子,它可以简化您的代码,将componentDidMountcomponentDidUpdate 的功能合并到函数 组件中:

useEffect(() => {
  setState({loaded: false}) 
  getMachineDetails();
}, [props.match.params.id]); // Only re-fetch if props.match.params.id changes

【讨论】:

  • 这是一个我什至没有看到的问题,直到 Don 帮助我清除了主要错误。我在您推荐的地方设置了 loaded=true ,但看起来组件没有重新渲染。有什么线索可以强制它更新吗?
【解决方案2】:

您在构造函数中为 this.state.motors 分配了一个空对象。这就是您收到错误的原因。应该是一个空数组。

【讨论】:

  • 没错,初始状态应该是一个空数组,虽然对象不是undefined,就像错误指出的那样
  • 是的,你是对的。虽然我认为他们应该得到另一个错误 this.state.motors.map 不是函数。
猜你喜欢
  • 1970-01-01
  • 2020-05-27
  • 1970-01-01
  • 2018-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 2018-12-18
相关资源
最近更新 更多