Ionic / React / TypeScript, навигация по реакции-маршрутизатору Анимация срабатывает дважды - PullRequest
2 голосов
/ 16 июня 2020

Итак, в основном я работаю над приложением Ionic / React Typescript, и есть этот странный переход страницы, который происходит дважды, когда я перемещаюсь по приложению (см. Gif ниже) который вызывается дважды, так как componentWillMount / didMount / willUnmount запускаются один раз, как и для страницы-толкателя, а также для толкаемой страницы.

enter image description here

Как как видите, переход всегда происходит дважды и нигде не нашел решения ... Используемые версии: - Ioni c: 5.2.1 - React: 16.9.0 (npm package) - Typescript 3.6.3 (npm package)

Here is the code for the page with the "Diplomes" Title:

class Diplome extends React.Component<RouteComponentProps> {

  // Function who redirect to the url for edit an situation
  redirectUrlToEditSituation = () => {
    this.props.history.push('/app/edit/diplome/', null);
  }

  render() {
    return (
      <IonPage>
          <IonHeader>
            <IonToolbar>
                <ButtonHambToolBar />
                <ToolBarLogo toolbarName={ToolBarName.DIPLOME}/>
            </IonToolbar>
          </IonHeader>
          <IonContent>
            <FabButtonAction ClickHandler={() => this.redirectUrlToEditSituation()} icon={add}/>
            <GenericList type={ModelType.DIPLOME}/>
          </IonContent>
      </IonPage>
    );
  }
}

export default (Diplome);

А вот страница с заголовком «Издания» при нажатии на кнопку:

class DiplomeEdit extends Component<DiplomeEditProps, {
    dataIsLoad: boolean,
    label_field: string,
    isAnCreate: boolean,
    openModalDelete: boolean,
    isValidation: boolean,
    currentDiplome: any
}>
{

    constructor(props: DiplomeEditProps) {
        super(props);
        this.state = {
            label_field: '',
            isAnCreate: true,
            openModalDelete: false,
            dataIsLoad: false,
            currentDiplome: '',
            isValidation: false,
        };
    }

    async componentWillMount() {
        console.log("component will mount");
        await this.getCurrentDiplomeToUpdate();
    }

    // Function who check if they are param on the url
    // If param exist get the current diplome on the store
    getCurrentDiplomeToUpdate = async () => {
        if (this.props.match.params.idDiplome !== undefined) {

            const diplomes: DiplomeInterface[] = this.props.diplomes;
            if (diplomes.length > 0) {
                const currentDiplomeReceive: DiplomeInterface | undefined = diplomes.find((res: DiplomeInterface) => {
                    return this.props.match.params.idDiplome === res.idDiplome;
                });

                if (currentDiplomeReceive !== undefined) {
                    this.setState({
                        isAnCreate: false,
                        label_field: currentDiplomeReceive.labelDiplome,
                        currentDiplome: currentDiplomeReceive,
                        dataIsLoad: true,
                    });
                }
            }

        } else {
            this.setState({
                isAnCreate: true,
                dataIsLoad: true,
            });
        }
    }

    // Function who render update button
    renderUpdateButton = () => {
        return (
            <div className="contenaire_button_action_situation_edit">
                <Button hidden={this.state.isAnCreate}
                    onClick={() => this.openOrCloseModalDeleteDialog()}
                    className="button_delete_situation">Supprimer</Button>
                <Button
                    onClick={e => this.actionClick()}
                    className="button_action_situation_edit">Enregistrer</Button>
            </div>
        );
    }

    // Function who delete diplome on the databse and on the store
    removeDiplome = async () => {
        await REQUEST.deleteDiplome(this.state.currentDiplome.idDiplome);
        store.dispatch(DELETE_DIPLOME(this.state.currentDiplome.idDiplome));
        this.props.history.replace('/app/diplomes');
    }

    // Function who get the label and id for create new diplome on the databae
    // Reset the state to the default init
    saveDiplome = async () => {
        const obj: DiplomeInterface = {
            idDiplome: Math.random().toString(36).substr(2, 9),
            labelDiplome: this.state.label_field.toLowerCase(),
        };
        this.setState({
            label_field: '',
            isAnCreate: false,
            openModalDelete: false,
        });
        await REQUEST.postDiplome(obj);
        store.dispatch(ADD_DIPLOME(obj));
        //this.props.history.replace('/app/diplomes');
        window.smartAlert("Diplome ajouté avec succès", "success", 5000);
        this.props.history.goBack();
    }

    // Function who update a diplome on the store
    // Need the current diplome
    // Label update
    updateDiplome = async () => {
        const currentDiplomeReceive: DiplomeInterface = this.state.currentDiplome;

        const obj: DiplomeInterface = {
            idDiplome: currentDiplomeReceive.idDiplome,
            labelDiplome: this.state.label_field,
        };

        if (this.props.userConnected.typeAccount === TypeConnect.ADMIN) {
            await REQUEST.updateDiplome(obj);
            store.dispatch(UPDATE_DIPLOME(obj));
            this.props.history.replace('/app/diplomes');
        }
    }

    // Function who checked what action we need
    actionClick = () => {
        if (this.state.isAnCreate) {
            this.saveDiplome();
        } else {
            this.updateDiplome();
        }
    }

    // Function call when input change
    inputChange = (e: any) => {
        this.setState({
            label_field: e.target.value,
        });
    }

    // Function who change the openModalDelete to true
    openOrCloseModalDeleteDialog = () => {
        if (this.props.userConnected.typeAccount === TypeConnect.ADMIN) {
            this.setState({
                openModalDelete: !this.state.openModalDelete,
            });
        }
    }

    render() {

        return (
            <IonPage>
                <IonHeader>
                    <IonToolbar className="task_cat_toolbar">
                        <IonBackButton
                            className="situation_edit_back_button" />
                        <ToolBarLogo toolbarName={ToolBarName.EDIT} />
                    </IonToolbar>
                </IonHeader>

                <IonContent>
                    <div className="contenaire_edit">
                        <div className="contenaire_form_situation">
                            <div className="contenaire_field">
                                <TextField
                                    onChange={e => this.inputChange(e)}
                                    value={this.state.label_field}
                                    className="field_form_situation"
                                    label="Libelle" />
                            </div>

                            <div className="container_task_situation_edit">

                                {!this.state.dataIsLoad && <SpinnerCircular />}

                                {this.renderUpdateButton()}

                                {
                                    this.state.openModalDelete &&
                                    <DialogDelete
                                        actionRemove={() => this.removeDiplome()}
                                        open={this.state.openModalDelete}
                                        actionCloseModal={() => this.openOrCloseModalDeleteDialog()} />
                                }

                            </div>
                        </div>
                    </div>
                </IonContent>

            </IonPage>
        );
    }

}

const mapStateToProps = (state: DiplomeEditProps) => ({
    diplomes: state.diplomes,
    network: state.network,
    role: state.role,
    userConnected: state.userConnected,
});

export default connect(mapStateToProps)(DiplomeEdit);

1 Ответ

0 голосов
/ 20 июня 2020

У меня такая же проблема. Кажется, что Ioni c React не go хорошо работает с историей и локациями. проверьте эту проблему GitHub .

Мне удалось обойти мою проблему, заключив мой компонент в React.memo, и вместо использования истории в pu sh я использовал Redirect from response- router-dom с состоянием для перенаправления.

...