React Native - родительский компонент обновления - PullRequest
0 голосов
/ 30 октября 2018

Я делаю приложение на реагирующем языке и столкнулся с небольшой проблемой. Я закончил первый макет, и теперь я хочу изменить стиль всего приложения со вторым макетом Это то, что у меня есть в моих родителях. Как видите, я использую AsyncStorage, чтобы при повторном открытии приложения проверить последний выбранный макет. Все работает отлично.

export default class Home extends React.Component
{
    constructor(props){
        super(props);
        this.state = {
            view:0
        }
    }
    componentWillMount()
    {
        this.checkStructureView();
    }
    checkStructureView = async() =>
    {
        const StructureView = await 
        AsyncStorage.getItem('@StructureView');
        if(StructureView == 1)
        {
            this.setState({
                view:1
            })
        }
        else
        {
            this.setState({
                view:0
            })
        }
    }
    render() 
    {
        if(this.state.view == 1)
        {
            return(
             <ChangeView/>
             ...
             )
        }
        else
        {
          return(
             <ChangeView/>
             ...
             )
        }
    }
}

И это мой компонент ChangeView. Это немного грязно, потому что у меня есть для каждой кнопки активные / неактивные стили. Это также работает отлично, но проблема в том, что когда я нажимаю на кнопку, чтобы изменить макет, он не будет меняться, только после того, как я обновлю приложение. Сначала я добавил это внутри родителя, и после того, как я обновил состояние, макет изменился мгновенно, но у меня есть больше страниц, где мне нужно добавить этот компонент, поэтому я использую компонент. Поэтому мой вопрос заключается в том, как я могу мгновенно обновить родительское состояние, чтобы мой макет менялся каждый раз, когда я нажимал на кнопку компонента, не перезагружая приложение.

import React, { Component } from 'react'
import {
    View,
    Text,
    Image,
    TouchableOpacity,
    AsyncStorage
} from 'react-native'

export default class ChangeView extends Component {
    constructor(props){
        super(props);
        this.state = {
            position: this.props.position,
            view:0,
            view1:require(`../assets/icons/view1_inactive.png`),
            view2:require(`../assets/icons/view2_active.png`)
        }
    }

    componentDidMount()
    {
        this.checkViewStructure();
    }
    checkViewStructure = async()=>
    {
        const StructureView = await AsyncStorage.getItem('@StructureView');
        if(StructureView == '0')
        {
            this.setState({
                view1:require(`../assets/icons/view1_inactive.png`),
                view2:require(`../assets/icons/view2_active.png`)
            })
        }
        else
        {
            this.setState({
                view1:require(`../assets/icons/view1_active.png`),
                view2:require(`../assets/icons/view2_inactive.png`)
            })         
        }
    }
    changeToList = async() =>
    {
        const StructureView = await AsyncStorage.getItem('@StructureView');
        if(StructureView == '0')
        {
            await AsyncStorage
            .setItem('@StructureView', '1')
            .then( () => {
                //
            })
            .catch( () => {
                alert('Something happened! Please try again later.');
            });
            this.setState({
                view1:require(`../assets/icons/view1_active.png`),
                view2:require(`../assets/icons/view2_inactive.png`)
            })
        }
    }
    changeToPics = async() =>
    {
        const StructureView = await AsyncStorage.getItem('@StructureView');
        if(StructureView == '1')
        {
            await AsyncStorage
            .setItem('@StructureView', '0')
            .then( () => {
                //
            })
            .catch( () => {
                alert('Something happened! Please try again later.');
            });     
            this.setState({
                view1:require(`../assets/icons/view1_inactive.png`),
                view2:require(`../assets/icons/view2_active.png`)
            })
        }
    }
    render()
    {

        if(this.state.position === 0) 
        return(
            <View style={{alignItems:'flex-end',marginTop:20,marginBottom:10,justifyContent:'flex-end',flexDirection:'row'}}>
                <View>
                    <TouchableOpacity
                    onPress= {() => this.changeToList()}
                    >
                    <Image
                    source={this.state.view1}
                    style={{width:15,height:21,margin:5}}
                    />
                    </TouchableOpacity>
                </View>
                <View>
                    <TouchableOpacity
                    onPress= {() => this.changeToPics()}
                    >
                    <Image
                    source={this.state.view2}
                    style={{width:15,height:21,margin:5}}
                    />
                    </TouchableOpacity>
                </View>
            </View>
        )
        else
        return null
    }
}

1 Ответ

0 голосов
/ 30 октября 2018

Компонент ChangeView только изменяет состояние в этом конкретном компоненте. Существует несколько способов распространения изменений на родительский компонент. Одним из способов является реализация onChange реквизита для компонента ChangeView. Ваша Home функция рендеринга компонента будет выглядеть примерно так:

render() {
  if(this.state.view == 1) {
    return(
      <ChangeView onChange={ (view) => this.setState({ view }) } />
      ...
    )
  } else {
    return(
      <ChangeView onChange={ (view) => this.setState({ view }) } />
      ...
    )
  }
}

Подробнее о реквизите можно прочитать здесь: https://reactjs.org/docs/typechecking-with-proptypes.html

Есть и другие способы сделать это, если у вас есть обработчик состояний для вашего приложения, например Redux.

...