简体   繁体   中英

RXJS in React without Subjects

I'm slowly picking up RXJS and learning how to use it in the context of React.

All the Rxjs tutorials I have found start off with observables. This makes sense. When I try and use an observable in react it doesn't work. I have to create a subject instead and push values into the subject.

Why is this the case? Why can't I use plain old observables in React? Am I doing something wrong? Can someone please explain why RXJS in react necessitates using subjects.

I realise this is a bit vague, but I don't yet understand the concepts to formulate a better question. Here is an example to illustrate what I am struggling to understand.

Here is a super simple component that takes a value in input value and displays it. regular react, no RXJS.

const InputBox = () => {
  const [value, setValue] = React.useState('');
  return (
    <>
      <p>{value}</p>
      <input value={value} onChange={e => setValue(e.target.value)}></input>
    </>
  );
};

If I want to do the same thing with RXJS, this works...

const inputStream$ = new Subject();

const InputBox = () => {
  const [value, setValue] = React.useState('');

  React.useEffect(() => {
    const subscription = inputStream$.subscribe(_value => setValue(_value));
    return () => subscription.unsubscribe();
  }, []);

  return (
    <>
      <p>{value}</p>
      <input
        value={value}
        onChange={e => inputStream$.next(e.target.value)}
      ></input>
    </>
  );
};

But if I try using a regular observable, no subject, then it doesn't work.

const inputStream$ = new Observable();

const InputBox = () => {
  const [value, setValue] = React.useState('');

  React.useEffect(() => {
    const subscription = inputStream$.subscribe(_value => setValue(_value));
    return () => subscription.unsubscribe();
  }, []);

  return (
    <>
      <p>{value}</p>
      <input
        value={value}
        onChange={e => inputStream$.next(e.target.value)}
      ></input>
    </>
  );
};

The next method exists on the observer, not the observable. A subject is both an observer and an observable, hence it has a next method. If you want to use a vanilla observable you need to pass the observer into the constructor. But why not use a subject, that is what they are for. A subject is also multicast so different components can subscribe to the same data more efficiently than with a plain observable.

Please refer to this answer . You can simply use the Async component and pass it your observables.

return (
    <Async select={[names$]}>
        {result => <div>{result}</div>}
    </Async>
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM