Skip to content

Instantly share code, notes, and snippets.

@getify
Created November 28, 2020 21:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save getify/699ed762e792bc0942ad692930ec72e4 to your computer and use it in GitHub Desktop.
Save getify/699ed762e792bc0942ad692930ec72e4 to your computer and use it in GitHub Desktop.
how to do this in react?
import React, { Component } from "react";
import MyStuffParent from "./my-stuff-parent";
import MyStuff from "./my-stuff";
export default class App extends Component {
constructor() {
super();
this.state = {
showMyStuff: true
}
}
render() {
return (
<MyStuffParent>
{this.state.showMyStuff && (
<MyStuff
stuff={ ** what do I put here? ** } // <------ HERE
changeStuff={ ** ditto? ** } // <------ HERE
/>
)}
</MyStuffParent>
);
}
}
import React, { Component, Fragment } from "react";
export default class MyStuffParent extends Component {
constructor() {
super();
this.state = {
stuff: 42
};
}
render() {
return (
<Fragment
stuff={this.state.stuff} // <------ HERE
changeStuff={v => { this.setState({ stuff: v }); }} // <------ HERE
>
{this.props.children}
</Fragment>
import React, { Component, Fragment } from "react";
export default class MyStuff extends Component {
constructor(props) {
super(props);
this.stuff = props.stuff;
this.changeStuff = props.changeStuff;
}
render() {
return ( .. );
}
}
@loucyx
Copy link

loucyx commented Nov 28, 2020

If I understand correctly, you want to set stuff in the children of MyStuffParent, and receive a onStuffChange event when children call that. A few considerations:

  1. Having state all over the place is not ideal, so you generally want to avoid that.
  2. Instead of having a component, you can have an util to handle this (which could use cloneElement internally).
  3. If you have props with names prepended by set/change/apply and so on, it's generally a sign that you aren't using the one-way data flow correctly. You only want value properties, and events (properties prepended by on).
  4. Ternaries are preferable to short-circuiting.

I guess would do it this way:

import { useState } from "react";

// No internal state, just props and events.
const MyStuff = ({ stuff, onStuffClick, ...props }) => (
  <div {...props}>
    {stuff}
    <button onClick={onStuffClick}>Click me!</button>
  </div>
);

// We have only state in this App container.
export const App = () => {
  const [showMyStuff, _setShowMyStuff] = useState(true);
  const [stuff, setStuff] = useState(42);

  // If you have several `MyStuff` here, you could use a map
  return showMyStuff ? (
    <MyStuff stuff={stuff} onStuffClick={() => setStuff(stuff + 1)} />
  ) : null;
};

Cheers!

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