首页 > 解决方案 > 将 props 从父级传递给子级在 React 中返回 undefined

问题描述

我正在学习 React,我正在构建一个简单的应用程序来试验道具。我有一个根据用户输入搜索数据库的输入字段,我想在搜索后加载的不同组件中显示结果,并且是 Search 组件的子组件。当我将数据从 Search 组件传递到 SearchResultsPage 组件时,我得到了它Cannot read property 'map' of undefined,但我不知道为什么,如何通过道具正确传递数据?这是我的搜索组件:

import React, { Component } from "react";
import Spinner from '../../components/Spinner/Spinner.jsx';
import SearchResultsPage from '../SearchResultsPage/SearchResultsPage.jsx';
import { Link } from 'react-router-dom';
import axios from "axios";

class Search extends Component {
    constructor(props) {
        super(props);

        this.state = {
            searchResults: [],
            isLoading: false,
            isSearchStringFound: true
        }
    }


    getSearchQuery = (event) => {
        const SEARCH_RESULTS_ENDPOINT = process.env.REACT_APP_SEARCH_ENDPOINT;

        const searchString = document.querySelector(".search-input").value;

        if (event.keyCode === 13) {
            this.setState({ ...this.state, isLoading: true });
            axios.post(SEARCH_RESULTS_ENDPOINT, {
                searchString: searchString,

            }).then(response => {
                this.setState({ ...this.state, searchResults: response.data });

                if (response.data.length === 0) {
                    this.setState({ ...this.state, isSearchStringFound: false });
                }

                else if (response.data.length > 0) {
                    this.setState({ ...this.state, isSearchStringFound: true });
                }

                this.setState({ ...this.state, isLoading: false });
                window.location.href = "/blog/searchResults"
            });
        }
    };

    render() {
        if (this.state.isLoading) {
            return <Spinner />
        }
        return (

            <div>
                <input
                    type="text"
                    placeholder="Search"
                    className="search-input"
                    onKeyDown={(e) => this.getSearchQuery(e)}

                />
                <div>
                    <SearchResultsPage
                        searchResults={this.state.searchResults}
                        isSearchStringFound={this.state.isSearchStringFound}
                    />
                </div>
            </div>
        );
    }
}

export default Search;

和我的 ResultsPage 组件:

import React, { Component } from 'react';
import { Link } from 'react-router-dom';

import Footer from '../Footer/Footer.jsx';
import CustomHeader from '../CustomHeader/CustomHeader.jsx';
let title = 'Blog'

class SearchResultsPage extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div>
                <CustomHeader
                    title={title}
                />
                <div>
                    {this.props.isSearchStringFound === false ? <div className="no-results-found">No results were found</div> : this.props.searchResults.map(result => (
                        <div key={result._id} >
                            <img src={result.picture} alt="avatar" />
                            <div >
                                <div>
                                    <h2>{result.title}</h2>
                                    <p>{result.date}</p>
                                    <p>{result.postContent}</p>
                                    <Link to={`/post/${result._id}`} className="read-more-btn">
                                        <button className="read-more-btn">Read more</button>
                                    </Link>
                                </div>
                            </div>
                        </div>
                    ))}
                </div>
                <Footer />
            </div>
        )
    }
};



export default SearchResultsPage;

标签: javascriptreactjs

解决方案


您没有正确更新状态。事件处理程序内的状态更新是批处理的并且是异步的,这就是为什么状态没有正确更新导致子组件中的错误

也不需要传播this.state,并且在 axios 调用后不需要重定向,因为组件已经呈现this.setState

您可以使用单个 setState 调用来更新您的状态,例如

 axios.post(SEARCH_RESULTS_ENDPOINT, {
            searchString: searchString,

        }).then(response => {
            const data = response.data;
            let isSearchStringFound;

            if (response.data.length === 0) {
                isSearchStringFound= false;
            }

            else if (response.data.length > 0) {
                isSearchStringFound = true;
            }

            this.setState({ isSearchStringFound, searchResults: data, isLoading: false });
        });

推荐阅读