4
votes

Existe-t-il un moyen de restituer un composant React.js fonctionnel sans setState?

J'ai un composant React fonctionnel qui doit être rendu après avoir changé la position d'un curseur. Étant donné que j'utilise Redux pour gérer mes états, je ne devrais pas avoir besoin d'utiliser React car pour moi, ce serait un peu un moyen piraté de résoudre mon problème. Existe-t-il un moyen réel de restituer ledit composant onChange sans convertir mon composant en un composant classique?

import React from "react";
import { Radio, RadioGroup } from "@material-ui/core";
import Slider from "@material-ui/lab/Slider";

const consoleLog = e => {
  console.log(e.target.name, ": ", e.target.value);
};

const handleData = question => {
  switch (question.type) {
    case "fv":
      return (
        <p
          className="range-field"
          style={{ width: 25 + "%", margin: 25 + "px" }}
        >
          <Slider
            value={25}
            min={question.min}
            max={question.max}
            onChange={consoleLog}
          />
        </p>
      );
  }
};

const Answers = props => {
  return <div>{handleData(props.data)} </div>;
};

export default Answers;


4 commentaires

Votre composant n'est pas connecté à Redux. Donc, il ne sera pas mis à jour si l'état du redux change ...


Le composant sera rendu à nouveau lorsque l'état change ou qu'il reçoit de nouveaux accessoires.


J'ai en fait retiré la partie où il est expédié, alors disons que c'est le cas.


vous pouvez utiliser des hooks de réaction reactjs.org/docs/hooks-intro.html


3 Réponses :


0
votes

vous pouvez utiliser la méthode forceUpdate pour forcer un rendu.

Documentation: https://facebook.github.io/react/docs /component-api.html


1 commentaires

Pas quelque chose qui est recommandé cependant.



2
votes

La position du curseur est en fait un état. Le composant d'interface utilisateur ( Slider ) est sans état et s'attend à ce que le composant parent ( Answers ) gère son état avec un flux de données unidirectionnel.

Dans le cas où il est préférable d'enregistrer l'état de l'interface utilisateur global state, Redux peut être utilisé pour gérer l'état du curseur.

Sinon, l'état local doit être utilisé. Un composant peut être converti en composant pour utiliser setState , ce n'est pas un piratage de l'utiliser car il s'agit en fait d'un état. Ou les composants fonctionnels peuvent utiliser les hooks React 16.8:

const Answers = props => {
    const [slide, setSlide] = useState(25);
    const onChange = useCallback(e => setSlide(e.value), []);
    const handleData = question => {
      switch (question.type) {
        case "fv":
          return (
            <p
              className="range-field"
              style={{ width: 25 + "%", margin: 25 + "px" }}
            >
              <Slider
                value={slide}
                min={question.min}
                max={question.max}
                onChange={onChange}
              />
            </p>
          );
      }
    };

    return <div>{handleData(props.data)} </div>;
};

useState préserve l'état du curseur entre les rendus des composants, useCallback empêche Rerenders Slider .


1 commentaires

Malheureusement, cela ne semble pas fonctionner. Lorsque je vais déplacer le curseur, la valeur de la diapositive devient indéfinie. Cela fonctionne initialement, en changeant la valeur de départ, mais devient ensuite indéfini lorsque je change la valeur. Erreur: "La valeur de l'accessoire est marquée comme requise dans Slider , mais sa valeur est indéfinie ".



0
votes

Je l'ai compris! J'utilise donc les hooks React, mais comme j'utilise material-ui, j'ai découvert que la valeur était transmise parallèlement à l'événement. Donc, en utilisant le code fourni par estus, j'ai ajouté de la valeur en tant que paramètre supplémentaire sur la fonction onChange afin de pouvoir obtenir ma valeur.

const Answers = props => {
const [slide, setSlide] = useState(props.data.min);
const onChange = useCallback((e, value) => setSlide(value), []);
const handleData = question => {
  switch (question.type) {
    case "fv":
      return (
        <p
          className="range-field"
          style={{ width: 25 + "%", margin: 25 + "px" }}
        >
          <Slider
            value={slide}
            min={question.min}
            max={question.max}
            onChange={onChange}
          />
        </p>
      );
  }
};

return <div>{handleData(props.data)} </div>;
};


0 commentaires