Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: storing components in an object

Tags:

reactjs

I have a few dozen fields in my users' profiles, and I'm trying to build an efficient means of displaying them in the appropriate input form components.

eg, a profile might look like:

profile1={
  name: 'Cornelius Talmadge',
  phone: '1'
}

And if I could stack components in something like this...

export const FieldCatalogue = {
  name: <TextField defaultValue={this.state.userProfile.name} label={"Name"} />
}

...then I could do something like this:

for (let field in Object.keys(profile1)) {
  return FieldCatalogue[field]
}

which would be super cool.

This question has a great answer for if my input components were all constructed via the normal syntax (eg, Component = React.createClass({..})), but:

a. that's a lot of boilerplate

b. i'd have to pass props galore to each one, which isn't optimal

The perfect situation for me would basically be passing input components almost as strings, such that they fell into the scope (state, props, etc.) of whatever parent component they were rendered.

Is this possible and/or advisable?

like image 871
Brandon Avatar asked Nov 09 '22 18:11

Brandon


1 Answers

The perfect situation for me would basically be passing input components almost as strings, such that they fell into the scope (state, props, etc.) of whatever parent component they were rendered.

Is this possible and/or advisable?

Yes, it is actually possible! No, I don't think this is something I would actually use. But it works, and it looks kinda cool. In my example, the FieldCatalogue components obviously don't have their own separate this.state object, but by binding them to the parent component this they automagically inherit the correct context.

Note that the example will not work if the components are defined as arrow functions, because arrow functions never have own this objects.

Oh, and the key in <Tmp key={i} /> is just there because we need to supply React with some kind of identifier when we loop over an array.

I had to try this as an exercise, and this is quite neat:

https://jsfiddle.net/dannyjolie/e9s09xrm/

const FieldCatalogue = {
  name: function() {
    return <input defaultValue = {this.state.userProfile.name} label = {"Name"}/>;
  },
  age: function() {
    return <input defaultValue = {this.state.userProfile.age}/>;
  }
}
const App = React.createClass({
  getInitialState: function() {
    return {
      userProfile: {
        name: 'Name in parent state',
        age: 'Age in parent state'
      }
    };
  },
  render: function() {
    let content = Object.keys(FieldCatalogue).map((objkey, i) => {
      let Tmp = FieldCatalogue[objkey].bind(this)
      return <Tmp key = {i} />;
    });
    return <div>{content}</div>);
  }
});

This way the thiscontext of the parent component is passed to the FieldCatalogue components, and it just works. Really not sure if it's a good thing to do though.

like image 196
dannyjolie Avatar answered Nov 15 '22 14:11

dannyjolie