【问题标题】:Trying to re-use component in other class and getting error: "Warning: setState(...): Can only update a mounted or mounting > component. "尝试在其他类中重用组件并出现错误:“警告:setState(...):只能更新已安装或正在安装的 > 组件。”
【发布时间】:2018-08-11 04:51:05
【问题描述】:

我正在整理一个小 POC,其中一部分正在执行搜索功能。这个想法是“搜索”将负责以下事情:
- 显示搜索输入表单(例如,文本、日期和位置参数)
- 点击后端 AWS Lambda 搜索 API
- 将结果对象返回给搜索对象
- 能够在多个页面上重复使用

我有两个不同的页面,我想利用“搜索”功能,但以不同的方式呈现结果。

搜索组件/表单独立工作,但我不知道如何将其嵌入其他网页。每当我尝试在“搜索表单”中输入任何内容时,控制台都会抛出以下错误:

index.js:2178 警告:setState(...):只能更新挂载或挂载 > 组件。这通常意味着您在未安装的组件上调用了 setState()。 > 这是无操作的。

请检查搜索组件的代码。

“搜索”代码如下,以及显示结果的页面开头。我是前端开发的新手,所以我可能在这里做一些愚蠢的事情......寻找关于我做错了什么的输入!感谢您的帮助。

import React, { Component } from "react";
import {FormGroup, FormControl, ControlLabel } from "react-bootstrap";
import LoaderButton from "../components/LoaderButton";
import "./Home.css";
import DatePicker from 'react-datepicker';
import moment from 'moment';
import PlacesAutocomplete from 'react-places-autocomplete';
import { searchAssets } from "../libs/awsLib";

import 'react-datepicker/dist/react-datepicker.css';

// CSS Modules, react-datepicker-cssmodules.css
import 'react-datepicker/dist/react-datepicker-cssmodules.css';


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

        this.state = {
            isLoading: false,
            freeText: "",
            startDate: null,
            endDate: null,
            radius: 5,
            address: '',
            searchResults: null
        };

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleStartDateChange = this.handleStartDateChange.bind(this);
        this.handleEndDateChange = this.handleEndDateChange.bind(this);
        this.handleLocationChange = this.handleLocationChange.bind(this);
    }

    // Basic change handling
    handleChange = event => {
        this.setState({ [event.target.id]: event.target.value });
    }

    // Location change needed because event.id cannot be taken from places object
    handleLocationChange = address => {
        console.log("The address has been changed: " + address);
        this.setState({ address: address });
    }

    // I need two separate handlers for each piece of the date range
    handleStartDateChange = date => {
        this.setState({ startDate: date });
    }

    handleEndDateChange = date => {
        this.setState({ endDate: date });
    }

    // 
    handleSubmit = async event => {
        event.preventDefault();
        console.log(event);

        // Construct the query string for AWS search

        var queryStatement = {
            accountId: 'account1', // Dummy
            groupId: 'group1', // Dummy
            caseId: '999', // Dummy
            freeText: this.state.freeText,
            radius: this.state.radius
        };

        if (this.state.startDate != null) {
            queryStatement['startDate'] = this.state.startDate.format("MM/DD/YYYY");
        }

        if (this.state.endDate != null) {
            queryStatement['endDate'] = this.state.endDate.format("MM/DD/YYYY");
        }

        if (this.state.address !== '') {
            queryStatement['address'] = this.state.address
        }

        console.log(queryStatement);

        this.setState({ isLoading: true });

        // Submit to the search API and load the Payload as a JSON object
        try {

            var resultSet;
            resultSet = await searchAssets(queryStatement);
            if (resultSet['StatusCode'] !== 200) {
                console.log("Error in lambda function");
            }
            console.log(JSON.parse(resultSet['Payload']));

            this.setState({
                isLoading: false,
                searchResults: JSON.parse(resultSet['Payload'])
            });

        }
        catch (e) {
            console.log(e);
            this.setState({ isLoading: false });
        }
    }

    render() {

        const autoLocationProps = {
          value: this.state.address,
          onChange: this.handleLocationChange,
        }

        console.log(this.state);

        // Only fetch suggestions when the input text is longer than 3 characters.
        const shouldFetchSuggestions = ({ value }) => value.length > 3


        return (
            <div className="Search">
                <form onSubmit={this.handleSubmit}>
                    <FormGroup controlId="freeText" bsSize="large">
                        <ControlLabel>Enter text to search on</ControlLabel>
                        <FormControl
                            type="textarea"
                            onChange={this.handleChange}
                            value={this.state.freeText}
                            placeholder="Enter any values to search on"
                        />
                    </FormGroup>
                    <FormGroup controlId="address" bsSize="large">
                        <ControlLabel>Enter search location</ControlLabel>
                        <PlacesAutocomplete 
                            inputProps={autoLocationProps}
                            shouldFetchSuggestions={shouldFetchSuggestions}
                            placeholderText="Start typing an address"
                        />
                    </FormGroup>
                    <FormGroup controlId="radius" bsSize="large">
                        <ControlLabel>Enter search radius</ControlLabel>
                        <FormControl
                            onChange={this.handleChange}
                            type="text"
                            value={this.state.radius}
                        />
                    </FormGroup>
                    <FormGroup controlId="startDate" bsSize="large">
                        <ControlLabel>Enter start date</ControlLabel>
                        <DatePicker
                            onChange={this.handleStartDateChange}
                            selected={this.state.startDate}
                            placeholderText="Enter start date"
                            isClearable={true}
                            maxDate={this.state.endDate}
                        />
                    </FormGroup>
                        <FormGroup controlId="endDate" bsSize="large">
                        <ControlLabel>Enter end date</ControlLabel>
                        <DatePicker
                            onChange={this.handleEndDateChange}
                            selected={this.state.endDate}
                            placeholderText="Enter end date"
                            isClearable={true}
                            minDate={this.state.startDate}
                        />
                    </FormGroup>
                    <LoaderButton
                        block
                        bsSize="large"
                        type="submit"
                        isLoading={this.state.isLoading}
                        text="Search for files"
                        loadingText="Searching..."
                    />
                </form>
            </div>
        );
    }
}

以表格形式查看:

import React, { Component } from "react";
import {Table, thead, tbody, th, tr, td } from "react-bootstrap";
import Search from "./Search";
import "./Home.css";

export default class Viewfiles extends Component {
    constructor(props) {
        super(props);
    }  

    render() {   

        // Eventually we will render the results in the table...
        var resultsObject = new Search();

        return (
            <div className="Viewfiles">
                {resultsObject.render()}
                <hr/>
                <Table striped condensed responsive >
                    <thead>
                        <tr>
                        <th>Thumbnail</th>
                        <th>Checksum</th>
                        <th>Address</th>
                        <th>Checksum</th>
                        <th>Description</th>
                        </tr>
                    </thead>
                </Table>
            </div>
        );
    }
}

【问题讨论】:

  • 你为什么要做new Search() 并手动调用渲染?您应该在 JSX 中使用&lt;Search /&gt;,而不是像任何其他组件一样。如果是这个问题,我会为它做一个答案

标签: javascript reactjs


【解决方案1】:

React 组件旨在在 JSX 中呈现,例如 &lt;Search /&gt;。如果你自己实例化它们,React 将不知道如何正确地挂载它们,包括状态和一切。

【讨论】:

    猜你喜欢
    • 2017-04-26
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 2017-03-02
    • 2019-08-15
    • 2016-09-25
    相关资源
    最近更新 更多