Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
197 views
in Technique[技术] by (71.8m points)

javascript - Is there a react way to store a mutable class instance objects in state?

React state shouldn't be mutated directly. But, what if the state is an instance of a class that shall be mutable with its own methods. Is there another way than having to deep-clone and re-instantiate the object with new parameters?

In General: What is the react way for a class object created in parent components to be used in subcomponents while maintaining its properties in the parent state (which is passed down via props/context)?

Sample class

class Car{
    constructor(data){
        this.data = data
    }
    changeColor = (newcolor) => this.data.color = newcolor
}

Sample Parent Component

const App = ({data}) => {
 const [car, setCar] = useState(new Car(data))
  return (
    <div>
      <CarViewer car={car} />
    </div>
  );
};

Sample Sub componeent

const CarViewer = ({car}) => {
  return (
    <div>
      The color is: {car.data.color}
    <button onClick={()=>car.changeColor("blue")}>Change color to blue </button>
    </div>
  );
};
question from:https://stackoverflow.com/questions/66062826/is-there-a-react-way-to-store-a-mutable-class-instance-objects-in-state

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think what you need to do is change your mental model of storing a class inside a react state and try different model like this which is more react way:

const CarViewer = ({ carData, changeColor }) => {
  return (
    <div>
      The color is: {carData.color}
      <button onClick={() => changeColor("blue")}>Change color to blue</button>
    </div>
  );
};

const App = ({ data }) => {
  const [carData, setCarData] = useState(data);

  const changeColor = (newcolor) =>
    setCarData((data) => ({ ...data, color: newcolor }));

  return (
    <div>
      <CarViewer carData={carData} changeColor={changeColor} />
    </div>
  );
};

EDIT: based on your comment, I think what you need is a custom hook like this:


const App = ({ data }) => {
  const { carData, changeColor } = useCar(data);
  
  return (
    <div>
      <CarViewer carData={carData} changeColor={changeColor} />
    </div>
  );
};

function useCar(defaultData = {}) {
  const [carData, setCarData] = useState(defaultData);

  const changeColor = (newcolor) =>
    setCarData((data) => ({ ...data, color: newcolor }));

  return {
    carData,
    changeColor,
    //... your other methods
  };
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...