1
votes

React - état de mise à jour des accessoires modifié - élément d'entrée

J'ai déjà lu toutes les questions de dépassement de capacité liées à ce problème, ainsi que ce post de réaction officiel et les solutions préférées.
Il n'est plus recommandé d'utiliser componentWillReceiveProps !

Avant de marquer cette question comme double, veuillez comprendre ma question spécifique, je n'ai vu aucune solution à mon problème spécifique.

Ce que j'essaye de faire est très simple:
J'ai le composant KInputRange qui a reçu la valeur des accessoires et envoie la valeur à l'événement (rappel) onEnter (enverra la valeur au serveur uniquement lors de l'entrée) La valeur des accessoires peut changer de manière aléatoire (provenant du serveur Websocket)

Ma question :
À l'intérieur de mes composants, l'attribut de valeur <input> obtiendra les données des props ou de l' state ?

If from props: Comment puis-je mettre à jour la valeur en interne lorsque l'utilisateur saisit des données?

If from state: Comment puis-je mettre à jour la nouvelle valeur si la valeur props.value a changé de manière aléatoire à partir du serveur?

Je dois en fait mettre à jour mon état interne sur le changement d'accessoires, mais comment le faire aujourd'hui, si réagit dit que c'est anti-modèle?

C'est mon code jusqu'à présent:

   <KInputRange value={this.state.dataFromTheServer}   onEnter={(val: number) => this.kInputRangeEnterClicked(val)}/>

Usage:

class KInputRange extends React.Component<any, any> {
    constructor(props: any) {
        super(props);
    }

    private onKeyDown(e: any): void {
        //If the key is enter call to props.onEnter with the current value

    }

    private onChange(e: any): void {
        //if user change the value- change the internal value
    }

    public render() {
        return (
            <input value={?????} type="text" onChange={(e) => this.onChange(e)} onKeyDown={(e) => this.onKeyDown(e)}/>
        );
    }
}


2 commentaires

Avez-vous essayé d'utiliser getDerivedStateFromProps, vous pouvez vérifier si les accessoires ont été modifiés et si oui, vous pouvez dériver l'état mis à jour.


Selon le document officiel, vous ne l'utiliserez que dans de rares cas, et mon cas est très trivial, aussi statique n'est pas bon, j'ai besoin de "ceci" pour faire plus de logique.


4 Réponses :


1
votes

Vous pouvez utiliser un composant de fonction comme mentionné dans l'article que vous avez lié ici. Pour mettre à jour la valeur en interne, vous pouvez utiliser le State Hook de React .

Quelque chose comme ça:

import React, { useState } from 'react';

const KInputRange = (props) => {

    const [value, setValue] = useState(props.value);

    function onKeyDown(e: any): void {
        //If the key is enter call to props.onEnter with the current value
    }

    function onChange(e: any): void {
        setValue(e.target.value);
    }

    return (
            <input value={value} type="text" onChange={(e) => this.onChange(e)} onKeyDown={(e) => this.onKeyDown(e)}/>
    );
}


0 commentaires

1
votes

Tout d'abord, comme @Atul l'a dit, vous devez utiliser getDerivedStateFromProps. Tout cela parce que vous devez contrôler la valeur de votre composant en fonction des deux: les accessoires et l'état interne. En supposant que vous utilisez le flux, ce code devrait vous aider:

// @flow
import * as React from "react";

type Properties = {
    remoteValue: string,
    onSubmit: (value: string) => void
};

type State = {
    remoteValueMemo: string,
    internalValue: string
};

class KInputRange extends React.Component<Properties, State> {

    static defaultProps = {
        remoteValue: "",
        onSubmit: () => {}
    };

    state = {
        remoteValueMemo: this.props.remoteValue,
        internalValue: this.props.remoteValue
    };

    static getDerivedStateFromProps(props: Properties, state: State) {
        if (state.remoteValueMemo !== props.remoteValue) {
            return {
                remoteValueMemo: props.remoteValue,
                internalValue: props.remoteValue};
        }
        return null;
    }

    handleValueChange = (event: SyntheticEvent<HTMLInputElement>) => {
        this.setState({internalValue: event.currentTarget.value});
    };

    handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
        if (event.keyCode === 13) {
            this.props.onSubmit(this.state.internalValue);
        }
    };

    render(): React.Node {
        const {internalValue} = this.state;

        return (
            <input value={internalValue} onChange={this.handleValueChange} onKeyDown={this.handleKeyDown}/>
        );
    }
}

export default KInputRange;


2 commentaires

Je le connais @Bender, et j'essaye aussi de l'utiliser, après avoir vu la doc officielle pour ne pas l'utiliser (seulement pour de rares cas) je comprends que mon cas très trivial n'est pas si trivial pour React, aussi je n'ai pas un accès à "this" (c'est statique) et je veux changer mon membre de classe privé interne sur le changement d'accessoires, donc ce n'est pas une bonne solution pour moi.


C'est le seul moyen de «réaction idéomatique» pour atteindre vos besoins (du moins pour l'instant). Il n'y a rien de spécial à voir avec le static il n'est utilisé que pour le nouvel état dérivé en fonction des modifications des accessoires de suivi des composants. Si vous souhaitez également implémenter un "effet secondaire" lorsque les accessoires sont modifiés, vous devez utiliser componentDidUpdate



-2
votes

Vous pouvez utiliser le hook useEffect chaque fois que vous avez besoin de faire quelque chose sur un changement d'accessoires spécifiques dans le composant de fonction

useEffect(() => {
    // You can place your logic here to run whenever value changes 
},[value]);

[valeur] est une dépendance de sorte que chaque fois que la valeur change, vous utilisez des appels de hook

L'espoir ci-dessus vous est utile.


1 commentaires

componentWillReceiveProps() considéré comme hérité et sera supprimé dans React 17 * vous devriez éviter de l'utiliser reactjs.org/docs/...



0
votes

L'argument passé à useState n'est pas utilisé pour mettre à jour l'état lors du nouveau rendu.

Vous devez utiliser le hook useEffect .

import React, { useEffect, useState } from 'react';

const Test = (props) => {

    const [value, setValue] = React.useState({...props.value});

    useEffect(() => {
        setValue(props.value);
    }, [props.value])
  
    //...
}

Sujet similaire ici: React.useState ne recharge pas l'état à partir des accessoires


0 commentaires