Guedda
@Guedda
Начинающий front-end разработчик

Какой метод необходимо вызвать при изменении props в дочернем компоненте?

Добрый день.
Есть вопрос новичка, но никак я не могу с ним справиться. Суть вот в чем.
Есть родительский компонент:
export default class App extends Component {

    constructor(props) {
        super(props);
        this.state = {
            response: false,                           
            selfUser: undefined,                       
            someId: undefined,
        }
    }

    getUser() {
        var self = this;
        someAjax().then(function(user) {
            if (user) {
                self.setState({response: true, selfUser: user, someId: user.someId});
            } else {
                self.setState({response: true, selfUser: undefined, someId: undefined});
            }
        });
    }

    setId(id) {
        this.setState({someId: id});
    }

    componentDidMount() {
        this.getUser();
    }


    render() {
        if (this.state.response) {
            let page;
            if (this.state.selfUser) {
                        page = (
                            <Child
                                sometId={this.state.someId}
                                setId={this.setId.bind(this)} />
                        );
            } else {
                page = (<div>No user</div>)
            }
            
            return (
                <div>
                    {page}        
                </div>
            )
        } else {
            return (
                <div>No response</div>
            )
        }
    }

}

Есть дочерний компонент:
export default class Child extends Component {

    constructor(props) {
        super(props);

        this.state = {
            status: "none",
            someData: undefined,
        }
    }

    getData() {
        $.ajax({
            url: 'someUrl'
            type: 'GET',
            success: function(data) {
                 this.setState({ status: "success", someData: data});
            }
        });
    }

    goToNextPage(item) {
        this.props.setId(item.Id);
    }

    renderDataChild(item) {
        let goToDataChildPage = this.goToNextPage.bind(this, item);
        return (
            <div key={item.Id} className="brick main-shadow">
                <div className="brick-inner" onClick={goToDataChildPage }><strong>{item.Name}</strong></div>
            </div>
        );
    }

    componentDidMount() {
        this.getData();
    }

    render() {
        switch (this.state.status) {
            case "none":
                return (<p></p>);
            case "success":
                if (this.state.someData) {
                    let someData = this.state.someData.values;
                    let tens = someData.map(function(obj) {
                        return this.renderDataChild(obj);
                    }.bind(this));

                    return (
                        <div>
                            {tens}
                        </div>
                    );
                } else {
                    return (
                        <div>No data</div>
                    );
                }
        }
    }

Когда всё загружается, я получаю все нормально. Но если я нажимаю на какой либо кирпичик, то вылетает ошибка:
Uncaught TypeError: Cannot read property 'map' of undefined

ругаясь на строку
let tens = someData.map(function(obj) {
Вставив консоль.лог в функцию getData и в render я увидел, что в первый раз вызывается и то и другое. А когда я на что-то нажал, вызывается только render.
Что я делаю не так? Понимаю, что вопрос новичка - но я и есть он.
Заранее благодарен за ответы.
  • Вопрос задан
  • 274 просмотра
Решения вопроса 1
maxfarseer
@maxfarseer
https://maxpfrontend.ru, обучаю реакту и компании
Когда у вас 1й раз происходит "и то и другое" - это ваш componentDidMount + render (у Child)
Когда вы "нажимаете на кирпичик", то у вас componentDidMount уже не происходит (судя по коду, так как компонент у вас не удаляется из DOM и не появлется там снова). Но так как вы по нажатию меняете у родителя что-то, и это что-то прокидываете в потомка - значит "ему пришли новые props", следовательно используйте componentWillReceiveProps, где в nextProps - будет то что вам нужно.

Документация про lifecycle methods

p.s. проверьте, у вас в тексте примера есть someId и sometId (опечатка)
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы