Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
const React = require("react");
const Lifecycles = React.createLifecycleEvents({
didMount({ setState }) {
setState({
disabled: false,
});
},
didUpdate({ inputRef }) {
if (document.activeElement !== inputRef.value) {
inputRef.value.focus();
}
}
});
// pass in initial state
const State = React.createState({
disabled: true,
text: "",
});
function TextboxView(props) {
const inputRef = React.createRef();
return (
<State>
{(state, setState) => (
<Lifecycles inputRef={inputRef} setState={setState}>
<input
{...props}
ref={inputRef}
disabled={state.disabled}
onChange={e => setState({text: e.target.value})}
value={state.text}
/>
</Lifecycles>
)}
</State>
);
}
const React = require("react");
const Lifecycles = React.createLifecycleEvents({
componentDidMount({ setState }) {
setState({
disabled: false,
});
},
componentDidUpdate({ inputRef }) {
if (document.activeElement !== inputRef.value) {
inputRef.value.focus();
}
}
});
const State = React.createState({
disabled: true,
text: "",
});
function ListView() {
const inputRef = React.createRef();
// "adopt" could be sugar syntax for React's callReturn functionality
const { state, setState } = adopt <State />;
return (
<Lifecycles inputRef={inputRef} setState={setState}>
<input
ref={inputRef}
disabled={state.disabled}
onChange={e => setState({text: e.target.value})}
value={state.text}
/>
</Lifecycles>
)
}
@TrySound
Copy link

TrySound commented Mar 4, 2018

Looks really nice. However we need to consider more cases.

  1. If you create ref object on every render then didUpdate will be triggered on every render. Is it what we expect?
  2. Where to keep ResizeObserver instance if we create it in didMount and should disconnect it in willUnmount?
  3. How to deal with getDerivedStateFromProps and shouldComponentUpdate?
  4. I think we should open RFC with adopt syntax. If I understand correctly it works like await.

@lmatteis
Copy link

lmatteis commented Mar 4, 2018

Cool but isn't this what recompose tries to do?

@streamich
Copy link

streamich commented Mar 4, 2018

What would adopt <State /> compile to?

@TrySound
Copy link

TrySound commented Mar 4, 2018

@streamich It's like await expansion. Every adopt statement creates new function scope.

function ListView() {
  const inputRef = React.createRef();
  return (
    <State>
      {({ state, setState }) => (
        <Lifecycles inputRef={inputRef} setState={setState}>
          <input 
            ref={inputRef} 
            disabled={state.disabled}
            onChange={e => setState({text: e.target.value})} 
            value={state.text}
          />
        </Lifecycles>
      )}
    </State>
  );
}

@TrySound
Copy link

TrySound commented Mar 4, 2018

@lmatteis Not quite. It's what react-powerplug tries to do.

@trueadm
Copy link
Author

trueadm commented Mar 4, 2018

@TrySound

  1. Tricky one. One approach might be for the update check to compare the value of a ref object, but that would be a special case. Another might be to put thee ref in the state.

  2. You would store ResizeObserver in state, just as you would with other "instance variables".

  3. getDerivedStateFromProps and shouldComponentUpdate could be done like:

const State = React.createState({ lastProps: null });

function MyComponent(props) {
  const shouldUpdate = ({lastProps}) => shallowCheck(lastProps, props);
  const deriveState = () => ({lastProps: props});
  const { state, setState } = adopt <State shouldUpdate={shouldUpdate} deriveState={deriveState} />;
  // ... rest of code
}

@OlegLustenko
Copy link

OlegLustenko commented Mar 5, 2018

Look like code similar to reason-react ideas

@drcmda
Copy link

drcmda commented Sep 9, 2018

I implemented a very basic POC for #2, using Reacts error bounds: https://codesandbox.io/embed/rr1838zvqm I'm guessing this will also more or less be the way in which suspense can read out fetchers (?), like Dan showed us in his talk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment