React ComponentDidUpdate 'this' не определен - PullRequest
0 голосов
/ 24 сентября 2019

Я пытаюсь обновить видимость столбцов после обновления компонента, основываясь на том, существует ли имя поля в массиве.Я получаю ошибку 'this' is undefined, поскольку она связана с this.updateColumnShow(field); в функции componentDidUpdate, но я не уверен, почему.Функция написана с использованием es6, поэтому нет необходимости связывать ее в конструкторе.Я вызываю отдельную функцию (this.setColumns) в componentDidUpdate, и это прекрасно работает.Чем отличается этот?

class QueryOptionsTable extends React.Component {

    constructor(props) {
        super(props);

        /*state values within the arrays are dynamic*/
        this.state = {
            columns: [],
            columnList: [],
            removedColumns: [],
            qryFieldSearch: ""
        }

        this.textInput = React.createRef();
    }

    componentDidMount() {
        this.props.actions.getQueryPreview(this.props.query);
        this.props.actions.getQueryRecordCount(this.props.query);
    }

    componentDidUpdate(prevProps, prevState) {
        //debugger;
        let fieldArray = JSON.parse(sessionStorage.getItem("qryFieldArray")); //returns fine
        if (prevProps.queryPreviewResults !== this.props.queryPreviewResults && this.props.queryPreviewResults.length > 0) {
            this.setColumns();
        }

        if (fieldArray.length > 0 && prevState.columnList !== this.state.columnList && this.state.columnList.length > 0) {
            /*Loop through the array list and use this value to mark column as show
            else remove column*/
            let columnsToHide = this.state.columnList.filter(x => !fieldArray.includes(x)); //getting correct results
            columnsToHide.forEach(function (field) {
                console.log("FIELD TO HIDE: ", field) //this logs correctly
                this.updateColumnShow(field); //this is undefined
            })
        }
    }

    setColumns = () => {
        Object.keys(this.props.queryPreviewResults[0]).map(key => {
            this.setState({ [key]: true });//monitor 'checked' property of checkbox?
            this.setState(prevState => ({
                columns: [...prevState.columns,
                {
                    Header: key,
                    accessor: key,
                    show: true,
                    width: 175
                }],
                columnList: [...prevState.columnList, key]
            }))

            return this.state;
        }
        )
    }

    focus = () => {
        // Explicitly focus the text input using the raw DOM API
        // Note: we're accessing "current" to get the DOM node
        this.textInput.current.focus();
    }

    /** show/hide columns. colums are all shown on first render. 
    * Checking them removed them from view
    */
    updateColumnShow = fieldName => {
        this.focus();
        this.setState({ [fieldName]: !this.state[fieldName] });
        this.setState(state => {
            const columns = state.columns.map(column => {
                if (column.Header === fieldName) {
                    column.show = !column.show;
                    if (!column.show === false) {
                        //add to list of columns to be removed
                        this.removeColumns(fieldName);
                    } else {
                        //remove from list of columns to be removed
                        this.addColumns(fieldName);
                    }
                    return column
                } else {
                    return column;
                }
            });
            return { columns }
        })
    }

RELEVANT JSX:

 <Col xs={3}>
                        <h6>Choose Columns:</h6>
                        <input
                            type="text"
                            value={this.state.qryFieldSearch}
                            onChange={this.updateQryFieldSearch}
                            placeholder="Search Field Names..."
                            className="form-control"
                            aria-describedby="searchbox"
                        ref={this.textInput}
                        />
                        <br />
                        <ul className="query-columns-selector">
                            <li>
                                <label>
                                    <input
                                        type="checkbox"
                                        name="removeAll"
                                        onChange={() => this.hideAllColumns()}
                                        className="form-check-input"
                                    />
                                    Remove All Columns</label>
                            </li>
                            {qryFieldFilteredList.map(listItem => (
                                <li key={listItem}>
                                    <label>
                                        <input
                                            id={listItem}
                                            checked={this.state[listItem]}
                                            className="form-check-input"
                                            type="checkbox"
                                            name={listItem}
                                            onChange={() => this.updateColumnShow(listItem)}
                                        />
                                        {listItem}</label>
                                </li>
                            )
                            )}
                        </ul>
                    </Col>

1 Ответ

2 голосов
/ 24 сентября 2019

Основное различие между setColumns и функцией в forEach заключается в том, что setColumns - это метод класса, то есть this будет привязан к объекту.Вы должны изменить функцию в forEach на функцию стрелки, потому что this в функциях стрелки относится к this внешней области видимости (в данном случае componentDidUpdate), которая относится к объекту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...