简体   繁体   中英

React data / component seperation, accessing complex class methods

I am not sure how to seperate my data from my components in complex circumstances: Imagine I am building a tabbed video game container that has an API like this:

const App = props =>
  <VideoGameContainerGroup tabbed searchable>
    <VideoGame id="cool-game-22" name="Cool Game, part 22" genre="RTS">
      <CoolVideoGame /> {/* Implementation goes here */}
    </VideoGame>
    <VideoGame id="something-wild" name="Craziest game ever" genre="button">
      <div>
        <h1>Some inline defined game-like component</h1>
        <button>click me</button>
      </div>
    </VideoGame>
    {/* ... more games .. */}
  </VideoGameContainerGroup>

It needs to not know about the game implementation, but wants to label the games somehow so it can index them, perform search and some other UI stuff:

class VideoGame extends component {
  getDynamicBio() {
    return `Hi, I am game ${this.props.name} fom genre ${this.props.genre}`;
  }
  render() {
    <div className="some-VideoGameContainer-boilerplate">
      {this.props.children /* implementation */}
    </div>
  }
}

class VideoGameContainerGroup extends Component {
  render() {
    return (
      <div>
        <div className="all-games">
          {this.props.children}
        </div>
        {/* ... code, which through sub componentes resolve to: */}
        <div className="SearchableGamesTabHeader">
            {React.Children.map(this.props.children, (game, i) => {
              { /* but here I need access to complex class methods */}
              <span>Game bio: {game.getDynamicBio()}</span>
              { /* this won't work */ }
            })}
        </div>
      </div>
    )
  }
}

I have considered exporting a bag of helper functions, for instance:

const getDynamicBio = (component) =>
  `Hi, I am game ${component.props.name} fom genre ${component.props.genre}`

But the methods are coupled to the VideoGame container and its data, and it seems weird to approach it this way.

I have considered doing something like:

<VideoGame videoGameData={ new VideoGameData({ id: 'cool-game-22', genre: 'RTS' }) }>
  <GameImplementation />
</VideoGame>

And then accessing the data through VideoGame.props.videoGameData. But my insticts tell me this is really wrong.

VideoGame really is the component that contains all that meta data, from an OO approach I would store my methods related to that on that class. How would I solve this in a maintainable way in React?

We dont access child component methods, in parent, directly, in react. If you want that, do something like this.

class VideoGameContainerGroup extends Component {
  render() {
    return (
      <div>
        <div className="all-games">
          {this.props.children}
        </div>
        {/* ... code, which through sub componentes resolve to: */}
        <div className="SearchableGamesTabHeader">
            {React.Children.map(this.props.children, (ChildEl, i) => {
              <ChildEl complexMethodAsCb = {()=>//pass in particular work you need to do say, on click} neededPropsInComplexMethod={...}/>
                   <span>Game bio: {game.getDynamicBio()}</span>
              </ChildEl/>
            })}
        </div>
      </div>
    )
  }
}

So we trickle data and methods from top in react. We pass whatever known data and methods we have in parent, to children and children call those, after/before there specific methods.

Further, we also try to remove all data/methods out of components, in react. This is where a pattern called flux comes in. You may check redux to further read and simplify this.

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