我的React状态不会停留在我的组件上

时间:2019-12-30 23:51:26

标签: javascript reactjs

在我的代码中,我在InterestBox上使用click事件,以更新InterestBox的外观并更改InterestBox父级的父级状态。

但是,当我使用React Developer Tools检查元素或尝试向我的API发送请求时,state.interests始终为空。但是,当我在控制台中记录状态时,它显示的数组长度为0,但包含所有正确的值。

我试图找到代码有什么问题,但是我认为我需要外在的外观来发现问题所在。

import axios from 'axios';
import * as Cookies from 'js-cookie';
import React, { Component } from 'react';
import Button from '../../components/Button';
import Dashboard from '../Dashboard';
import ErrorContainer from '../../components/ErrorContainer';
import InterestList from '../../components/register/InterestList';

export class EditUser extends Component {
    constructor(props) {
        super(props);
        this.state = {loading: true, interests: []}
        this.addInterest = this.addInterest.bind(this);
        this.logState = this.logState.bind(this);
    }

    addInterest(id, name) {
        console.log('hoppity hippity you parenty')
        var mid = 'm' + id;
        console.log(this.state.interests[mid] == undefined)

        if(this.state.interests[mid] == undefined) {
            console.log(this.state);
            this.setState((state) => {
                state.interests[mid] = name;
                return {interests: state.interests}
            }, () => {
                console.log(JSON.stringify(this.state.interests))
            })
        } else {
            console.log('deleted')
            var newInterest = this.state.interests;
            delete newInterest[mid]
            this.setState({interests: newInterest})
        }
        console.log(this.state.interests)
    }

    componentDidMount() {
        var token = Cookies.get('token');
        axios.get('http://localhost:8000/api/details', {headers: {"Accept": 'application/json', "Authorization": `Bearer ${token}`}}).then(
            (success) => {
                this.setState({
                    loading: false,
                    firstname : success.data.data.user.firstname, 
                    lastname: success.data.data.user.lastname, 
                    email: success.data.data.user.email,
                    dob: success.data.data.user.dob,
                    address: success.data.data.user.address,
                    uinterests: success.data.data.interests
                })
            }, (error) => {
                this.props.history.push('/deconnexion');
            }
        )
        var places = require('places.js');
        var placesAutocomplete = places({
        appId: "plZJLSHIW8M5",
        apiKey: "0eddd2fc93b5429f5012ee49bcf8807a",
        container: document.querySelector('#address-input')
        });
    }

    logState() {
        console.log(this.state);
    }
    render() {
        return (
            <Dashboard loading={this.state.loading}>
                <h1 className="title">Modifier mon profil</h1>
                <form className="user-form offer-update-form" onSubmit={this.handleSubmit}>
                <label>Prénom :</label>
                <input type="text" name="firstname" value={this.state.firstname} onChange={this.handleChange}></input> <br />
                <label>Nom de famille :</label>
                <input type="text" name="lastname" value={this.state.lastname} onChange={this.handleChange}></input> <br />
                <label>Email :</label>
                <input type="email" name="email" value={this.state.email} onChange={this.handleChange} /><br />
                <label>Adresse :</label>
                <input type="address" id="address-input" name="address" value={this.state.address} onChange={this.handleChange} /><br />
                <label>Date de naissance :</label>
                <input type="date" name="dob" value={this.state.dob} onChange={this.handleChange} /><br />
                <InterestList alreadyChecked={this.state.uinterests} onClick={this.addInterest} />
                <ErrorContainer errors={this.state.errors} />
                <Button type="primary">Soumettre les changements</Button>
                </form>
                <Button type="danger" onClick={this.logState} />
            </Dashboard>
        )
    }
}

export default EditUser
```

```
import React, { Component } from 'react'
import InterestBox from './InterestBox'
import Axios from 'axios'

export class InterestList extends Component {

    constructor(props) {
        super(props);
        this.state = {pinterests: []}
        this.pinterestRefs = React.createRef()
        this.pinterestRefs.current = [];
    }

    componentDidMount() {
        Axios.get('http://localhost:8000/api/interests')
        .then((success) => {
            this.setState({pinterests: success.data.data.interests});
        })
    }

    componentDidUpdate(prevProps) {
        console.log(JSON.stringify(prevProps));
        console.log(JSON.stringify(this.props))
        if(this.props.alreadyChecked != prevProps.alreadyChecked) {
            this.props.alreadyChecked.forEach((item) => {
                this.pinterestRefs.current.forEach((pinterest) => {
                    if(item == pinterest.props.id) {
                        console.log(pinterest)
                        pinterest.handleClick();
                    }
                })
                console.log(item)
            })
        }
        console.log(this.pin)
    }

    render() {
        return (
            <React.Fragment>
                {Object.keys(this.state.pinterests).map((interest, i) => {
                    var pinterest = this.state.pinterests[interest];
                    var callbackRef = node => this.pinterestRefs.current[i] = node;
                    return <InterestBox id={pinterest.id} onClick={this.props.onClick} icon={pinterest.picture_src} title={pinterest.name} ref={callbackRef} />
                })}
            </React.Fragment>
        )
    }
}

export default InterestList
```

```
import React, { Component } from 'react'
export class InterestBox extends Component {

    constructor(props) {
        super(props);
        this.images = require('../../img/interests/*.svg');

        this.state = {activated: false};
        this.interest_box_content = React.createRef();
        this.interest_text = React.createRef();
        this.handleClick = this.handleClick.bind(this);
        this.updateDimensions = this.updateDimensions.bind(this);
    }

    handleClick() {
        console.log('hoppity hippity you clicky')
        this.props.onClick(this.props.id, this.props.title);
        this.setState(prevState => ({
            activated: !prevState.activated
        }))        
    }

    updateDimensions() {
        console.log((window.getComputedStyle(this.refs.interest_box_content).width))
        this.refs.interest_text = (window.getComputedStyle(this.refs.interest_box_content).width)
    }

    render() {
        return (
            <div className="column is-one-fifth-desktop is-half-touch">
                <div className="interest-box">
                    <div className="interest-box-adjuster">
                        <div ref={"interest_box_content"} className={"interest-box-content " + (this.state.activated == true ? 'interest-box-activated' : '')} onClick={this.handleClick}>
                            <img className="interest-icon" src={this.images[this.props.icon]} style={{'height': '50%'}}></img>
                            <i className="activated-icon fas fa-check"></i>
                            <span ref={"interest_text"} className="interest-text">{this.props.title}</span>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

export default InterestBox

```

1 个答案:

答案 0 :(得分:1)

您已使用[]将兴趣初始化为一个数组

但是随后,您将其更新为地图state.interests[mid] = name;

注意:JS不是类型安全的。在上述声明之后,兴趣不再是一个数组

这就是为什么在控制台上您可以看到它正在填充但数组长度为0的原因。这是因为您现在正在输出一个对象而不是一个数组。