setState родительского не запускает componentWillReceiveProps дочернего - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть родительский компонент и дочерний компонент с некоторыми реквизитами, связанными с родительским состоянием.

В родительском я вызываю setState, но функция componentWillReceiveProps дочернего элемента не запускается.
Более точно, он срабатывает в определенной точке родителя, не срабатывает в другой точке.

Это родитель:

... imports

class HomeScreen extends Component {

    constructor(props) {
        super(props);

        dispatchFbPermissionAction = this.dispatchFbPermissionAction.bind(this);

        this.state = {
            fbPermissions: [],
        }
    }

    componentDidMount () {
        this._loadInitialState();
    }

    _responsePermissionsCallback(error: ?Object, result: ?Object) {
        if (error) {
            log('Error fetching data: ' + error.toString());
        } else {
            dispatchFbPermissionAction(result.data);
        }
    }

    dispatchFbPermissionAction = (data) => {
        // **NOT FIRED**
        this.setState({
            fbPermissions: data
        });

        this.props.fbPermissionsLoaded(data);
    }

    async _loadInitialState() {
        AccessToken.getCurrentAccessToken().then(
            (data) => {
                if (data) {
                    const infoRequest = new GraphRequest(
                      '/me/permissions',
                      null,
                      this._responsePermissionsCallback,
                    );
                    new GraphRequestManager().addRequest(infoRequest).start();

                    // **FIRED**
                    this.setState({
                        ...
                    });

                    this.props.loggedIn();
                }
            }
        );
    }

    render () {
        const { navigation } = this.props;

        return (
            <Container>
                <ScrollableTabView
                    <View tabLabel="ios-film" style={styles.tabView}>
                        <Text style={styles.tabTitle}>{_.toUpper(strings("main.theatres"))}</Text>
                        <ListTheatre navigation={this.props.navigation} filterText={this.state.filterText} isLoggedIn={this.state.isLoggedIn} fbPermissions={this.state.fbPermissions}></ListTheatre>
                    </View>
                </ScrollableTabView>
            </Container>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        isLoggedIn: state.isLoggedIn,
        listTheatre: state.listTheatre,
        listMusic: state.listMusic
    };
};

// wraps dispatch to create nicer functions to call within our component
const mapDispatchToProps = (dispatch) => ({
    startup: () => dispatch(StartupActions.startup()),
    loggedIn: () => dispatch({
        type: LOGGED_IN
    }),
    fbPermissionsLoaded: (data) => dispatch({
        type: FB_PERMISSIONS_LOADED,
        fbPermissions: data
    })
});

export default connect(mapStateToProps, mapDispatchToProps)(HomeScreen)

А это ребенок:

... imports

class ListTheatre extends Component {

    constructor(props) {
        super(props);

        this.state = {
            ...
        }
    }

    componentWillReceiveProps(nextProps) {
        log(this.props)
    }

    shouldComponentUpdate(nextProps, nextState) {
        return !nextState.fetching;
    }

    render() {
        const { navigate } = this.props.navigation;

        return (
            <SectionList
                ...
            />
        )
    }
}

ListTheatre.propTypes = {
    isLoggedIn: PropTypes.bool.isRequired,
}

const mapStateToProps = (state) => {
    return {
        isLoggedIn: state.isLoggedIn
    };
};

const mapDispatchToProps = (dispatch) => ({
    startup: () => dispatch(StartupActions.startup())
});

export default connect(mapStateToProps, mapDispatchToProps)(ListTheatre);

Я не понимаю, почему setState после вызова GraphRequestManager().addRequest работает как чудо (срабатывает функция componentWillReceiveProps дочернего объекта), в то время как setState в функции dispatchFbPermissionAction не запускает функцию componentWillReceiveProps дочернего объекта.

1 Ответ

0 голосов
/ 10 сентября 2018

Это происходит из-за connect / Connect(ListTheatre), который оборачивает ваш компонент ListTheatre, реализованный sCU (shouldComponentUpdate) внутренне для вас, отключите его, установив для чистой опции подключения значение false, например

export default connect(mapStateToProps, mapDispatchToProps, null, {pure: false})(ListTheatre)

[pure] (Boolean): если true, connect () будет избегать повторного рендеринга и вызовов mapStateToProps, mapDispatchToProps и mergeProps, если соответствующие объекты state / props остаются равными на основе их соответствующих проверок на равенство. Предполагается, что обернутый компонент является «чистым» компонентом и не зависит от какого-либо ввода или состояния, кроме его параметров и состояния выбранного хранилища Redux. Значение по умолчанию: true

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