React Native: массив объектов setState не обновляется - PullRequest
0 голосов
/ 12 июля 2020

Когда я вызываю setState для массива объектов, он не срабатывает, что бы я ни делал. Я предполагаю, что у меня есть функция, которая не привязана должным образом, но я работал над этим слишком долго. Проблемной областью являются нижние строки функции SubmitLineItem, рядом со всеми строками есть комментарии. Последовательность действий выглядит следующим образом:

  • пользователь находится на экране для позиций, нажимает кнопку, чтобы отобразить всплывающее окно действий
  • пользователь вводит данные в лист действий (цена, стоимость налога и количество), и нажимает submit
  • лист действий закрывается и отправляет данные обратно на родительскую страницу, где должен быть сохранен новый элемент строки
  • пользователь нажимает сохранить, чтобы вызвать POST api для отправить данные.

Проблема в том, что я не могу заставить массив состояний принять новую строку. Я сдался на этом этапе. Родительская страница - это details.lineitems, лист действий - action.sheet.

export default class DetailsLineItems extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            id: props?.route?.data?.id,
            user: props?.route?.user,
            loading: true,
            types: [],
            isActionSheetOpen: false,
            lineItems: [],
            total: 0,
            newLineItems: []
        };
        this.SubmitLineItem = this.SubmitLineItem.bind(this);
        this.PostNewLineItems = this.PostNewLineItems.bind(this);
    }

    CloseActionSheet = () => {
        this.setState({ ...this.state, isActionSheetOpen: false })
    }

    AddLineItemButtonOnPress() {
        this.setState({ ...this.state, isActionSheetOpen: true });
    }

    SubmitLineItem(type, quantity, tax, price) {
        if (type === "" || type === 0) return;
        if (quantity === 0) return;
        if (tax === 0) return;
        if (price === 0) return;

        let item = this.state.types.find(x => x.id === type);
        
        let newLineItem = {
            id: 0,
            workorderId: this.state.id,
            description: "",
            unitPrice: price,
            qty: quantity,
            tax: tax, 
            assetId: null,
            typeId: item.id,
            active: "true",
            price: 0
        }

        var arr = this.state.newLineItems.slice();
        console.log("arr", arr); //copies the array, outputs as expected (empty array)
        arr.push(newLineItem);
        console.log("arr push", arr); //added new item, array is updated as expected (1 object in array)
        //this.setState({ newLineItems: arr }, function() { console.log("setState",  this.state.newLineItems) }); //does not work, array is empty...
        //this.setState({ ...this.state, newLineItems: [ ...this.state.newLineItems, newLineItem ], function () { console.log("setState", this.state.newLineItems) } }); //also does not work, array is empty...
        this.setState(prevState => ({ newLineItems: [...prevState.newLineItems, newLineItem] })); //again, doesnt work, array is empty...
    }

    async PostNewLineItems() {
        console.log("newlineitems", this.state.newLineItems) *doesnt work, array shows empty*
    }
    
    render() {
        return (
            <> (whole lotta UI junk)

                <ActionSheet types={this.state.types} userType={this.state?.user?.userType} isVisible={this.state.isActionSheetOpen} SubmitLineItem={this.SubmitLineItem} CloseActionSheet={this.CloseActionSheet} />

                            <Button title={ "Save" }
                                    color={ "#0A1F44" }
                                    style={ styles.bottomButton }
                                    onPress={ this.PostNewLineItems }/>
            </>
        );
    }
}

Ниже приведен файл action.sheet.

export default class ActionSheet extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            typeSelect: "",
            qty: 0,
            tax: 0,
            price: 0
        };
    }

    CloseSheetAndSendData() {
        this.props.SubmitLineItem(this.state.typeSelect, this.state.qty, this.state.tax, this.state.price);
        this.props.CloseActionSheet();
        this.setState({ typeSelect: "", qty: 0, tax: 0, price: 0 })
    }

    render() {
        return (
            <> (more UI junk)                  
                                <Button
                                        onPress={ this.CloseSheetAndSendData.bind(this) }
                                        style={ styles.button }
                                        color="#0A1F44"
                                        title="SUBMIT" />
                        </View>        
                    </View>
                }
            </>
        );
    }
}
...