Я создаю файловый менеджер webui base на response redux (моя цель - освоить реакцию и уменьшить этот проект)Как реализовать автономный компонент в реакции редукции?
Как известно, файловому менеджеру нужен древоискатель. Я хочу построить компонент, который может содержать его сам, и каждый имеет собственное состояние. как показано ниже:
TreeNode
может содержать детей, которые TreeNode
too.Each TreeNode
держать его состояние {path, children_nodes, right .....}
, children_nodes
это получить от сервера, path
передается от родителей. Вот что я себе представляю. Struct как:
App:
TreeNode
--TreeNode
----TreeNode
----TreeNode
TreeNode
TreeNode
--TreeNode
TreeNode
--TreeNode
----TreeNode
----TreeNode
Но беда приходят сюда, потому что перевождь connect
магазин корень дерева, все узел под корень получить то же самое состояние ...
К примеру, у меня есть OPEN_NODE
действие, которое является дизайн для запуска getFileList fucntion
базового пути этого узла и установить данный узел state.open
к true
(примечанию: getFileList fucntion
еще не реализовать, просто дать ложные данные сейчас). на снимке экрана:
Нажмите каждый элемент, но states are equal
.
Мой код:
контейнеры/App.js
import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import Footer from '../components/Footer';
import TreeNode from '../containers/TreeNode';
import Home from '../containers/Home';
import * as NodeActions from '../actions/NodeActions'
export default class App extends Component {
componentWillMount() {
// this will update the nodes on state
this.props.actions.getNodes();
}
render() {
const { nodes } = this.props
console.log(nodes)
return (
<div className="main-app-container">
<Home />
<div className="main-app-nav">Simple Redux Boilerplate</div>
<div>
{nodes.map(node =>
<TreeNode key={node.name} info={node} actions={this.props.actions}/>
)}
</div>
{/*<Footer />*/}
</div>
);
}
}
function mapStateToProps(state) {
return {
nodes: state.opener.nodes,
open: state.opener.open
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(NodeActions, dispatch)
};
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App);
контейнеры/TreeNode.js
import React, { Component, PropTypes } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import classNames from 'classnames/bind'
import * as NodeActions from '../actions/NodeActions'
export default class TreeNode extends Component {
constructor(props, context) {
super(props, context)
this.props = {
open: false,
nodes: [],
info:{}
}
}
handleClick() {
let {open} = this.props
if (open) {
this.props.actions.closeNode()
} else {
this.props.actions.openNode()
}
}
render() {
const { actions, nodes, info } = this.props
return (
<div className={classNames('tree-node', { 'open':this.props.open})} onClick={() => {this.handleClick()} }>
<a>{info.name}</a>
{nodes &&
<div>{nodes.map(node => <TreeNode info={node} />)}</div>
}
{!nodes &&
<div>no children</div>
}
</div>
);
}
}
TreeNode.propTypes = {
open:PropTypes.bool,
info:PropTypes.object.isRequired,
nodes:PropTypes.array,
actions: PropTypes.object.isRequired
}
действия/NodeActions.js
import { OPEN_NODE, CLOSE_NODE, GET_NODES } from '../constants/NodeActionTypes';
export function openNode() {
return {
type: OPEN_NODE
};
}
export function closeNode() {
return {
type: CLOSE_NODE
};
}
export function getNodes() {
return {
type: GET_NODES
};
}
редукторы/TreeNodeReducer .js
import { OPEN_NODE, CLOSE_NODE, GET_NODES } from '../constants/NodeActionTypes';
const initialState = {
open: false,
nodes: [],
info: {}
}
const testNodes = [
{name:'t1',type:'t1'},
{name:'t2',type:'t2'},
{name:'t3',type:'t3'},
]
function getFileList() {
return {
nodes: testNodes
}
}
export default function opener(state = initialState, action) {
switch (action.type) {
case OPEN_NODE:
var {nodes} = getFileList()
return {
...state,
open:true,
nodes:nodes
};
case CLOSE_NODE:
return {
...state,
open:false
};
case GET_NODES:
var {nodes} = getFileList()
return {
...state,
nodes:nodes
};
default:
return state;
}
}
Для полного кода, см моего GitHub https://github.com/eromoe/simple-redux-boilerplate
Я не вижу пример сопроводительного такой компонента, и Google результат ничего не полезно. Любая идея преодолеть это?
обновление: Я вижу это How to manage state in a tree component in reactjs
Но решение передать все дерево в состояние, не может использовать в файловом менеджере.
Посмотрите на [вычисления полученных данных] (http://redux.js.org/docs/recipes/ComputingDerivedData.html) в Redux. –