Skip to content Skip to sidebar Skip to footer

How To Implement A Self Contained Component In React Redux?

I am building a file manager webui base on react redux(My purpose is to master react and redux through this project) As you know, a file manager need a tree explorer.I want to buil

Solution 1:

I'm implementing a Github like app using React and Redux.

For now, I only list repositories and show its files as well as navigate through them.

I don't know if this is considered a good or bad practice, but this is how I implemented my Tree component.

Inside each Tree Component, I have a Link to itself. And I pass some data on the route, so I'm able to get the next tree when I render it.

App

Component

class Tree extends Component {
  constructor(props) {
    super(props);

    this.renderList = this.renderList.bind(this);
  }

  componentWillMount() {
    this.props.getTree(this.props.params.sha);
  }

  componentWillReceiveProps(nextProps) {
    if(nextProps.params.sha !== this.props.params.sha) {
      this.props.getTree(nextProps.params.sha);
    }
  }

  renderList(file) {
    return (
      <tr key={ file.sha }>
        { file.type == 'tree'
       ? <td><Link to={`/repository/${this.props.params.repoName}/tree/${file.path}/${file.sha}`}>{ file.path }</Link></td>
       : <td><Link to={`/repository/${this.props.params.repoName}/blob/${file.sha}/${file.path}`}>{ file.path }</Link></td>}
      </tr>
    )
  }

  render() {
    const treeFile = this.props.tree;
    const fileName = this.props.params.path;

    return (
      <div className="row">
        <h3>{ fileName }</h3>
        <div className="col-md-12">
          <table className="table table-hover table-bordered">
            <tbody>
              { isEmpty(treeFile.tree) ? <tr>Loading</tr> : treeFile.tree.map(this.renderList) }
            </tbody>
          </table>
        </div>
      </div>
    )
  }
}
export default Tree;

Action

const setTree = (tree) => {
  return {
    type: actionTypes.GET_TREE,
    tree
  };
};

export const getTree = (sha) => {

  return (dispatch, getState) => {
    const { repository, profile } = getState();
    const repo = GitHubApi.getRepo(profile.login, repository.name);

    repo.getTree(sha, function(err, data) {
      dispatch(setTree(data));
    });
  }
}

Reducer

const initialState = "";

export const tree = (state = initialState, action) => {
  switch (action.type) {
    case actionTypes.GET_TREE:
      return getTree(state, action);
  }
  return state;
}

const getTree = (state, action) => {
  const { tree } = action;
  return tree;
}

For the complete code, you can check my repository on github

https://github.com/glundgren93/Github-redux


Solution 2:

All of your TreeNode has the same state from redux because your mapStateToProps for all of them are same.

mapStateToProps can take ownProps (the props of the wrapped component) as second parameter. You can use it to distinguish your TreeNodes. In your case, path is a good option.

considering writing a state selector like this getChildrenNodes(state, path) and return the nodes accordingly.

You may want to consider reading through redux docs first, especially this seciont: http://redux.js.org/docs/recipes/ComputingDerivedData.html


Post a Comment for "How To Implement A Self Contained Component In React Redux?"