简体   繁体   English

将 props 从父级传递给子级在 React 中返回 undefined

[英]Passing props from parent to child returns undefined in React

I am learning React and I am building a simple app to experiment with props.我正在学习 React,我正在构建一个简单的应用程序来试验道具。 I have an input field that searches the database based on the user input and I want to display the results in a different component that loads after the search and is a child to the Search component.我有一个根据用户输入搜索数据库的输入字段,我想在搜索后加载的不同组件中显示结果,并且是 Search 组件的子组件。 When I pass the data from the Search component to the SearchResultsPage Component I get that Cannot read property 'map' of undefined and I don't know why, how can I pass the data properly via props?当我将数据从 Search 组件传递到 SearchResultsPage 组件时,我得到Cannot read property 'map' of undefined并且我不知道为什么,如何通过道具正确传递数据? Here is my Search component:这是我的搜索组件:

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;

and my ResultsPage component:和我的 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;

You aren't updating the state correctly.您没有正确更新 state。 State updates inside event handlers are batched and are asynchronous which is why the state isn't correctly updated causing the error in child component State 事件处理程序内的更新是批处理的并且是异步的,这就是为什么 state 没有正确更新导致子组件中的错误

Also spreading this.state with this.setState isn't needed and you shouldn't be needed to redirect after axios call as the component is already rendered也不需要使用this.setState传播this.state并且在 axios 调用后不需要重定向,因为组件已经呈现

You can update your state with a single setState invocation like您可以使用单个 setState 调用更新您的 state,例如

 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 });
        });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM