reactjs - tabla - tipos de componentes react
Anidar un componente contenedor en un componente de presentación (1)
Para responder específicamente a su pregunta: está bien anidar componentes de presentación y contenedor. Después de todo, todos son solo componentes. Sin embargo, en interés de las pruebas fáciles, preferiría anidar componentes de presentación sobre componentes de contenedor. Todo se reduce a una clara estructuración de sus componentes. Encuentro que comenzar en un solo archivo y luego lentamente la integración de componentes funciona bien.
Eche un vistazo a los niños this.props.children
y utilice this.props.children
para envolver elementos secundarios en un componente de presentación.
Ejemplo (se eliminó algún código por brevedad)
Lista (componente de presentación)
import React, { Component, PropTypes } from ''react'';
export default class List extends Component {
static propTypes = {
children: PropTypes.node
}
render () {
return (
<div className="generic-list-markup">
{this.props.children} <----- wrapping all children
</div>
);
}
}
Todo (componente de presentación)
import React, { Component, PropTypes } from ''react'';
export default class Todo extends Component {
static propTypes = {
description: PropTypes.string.isRequired
}
render () {
return (
<div className="generic-list-markup">
{this.props.description}
</div>
);
}
}
TodoList (componente contenedor)
import React, { Component, PropTypes } from ''react'';
import { connect } from ''react-redux'';
import { createTodo, updateTodo, deleteTodo } from ''actions'';
import List from ''components/List'';
import Todo from ''components/Todo'';
export class TodoList extends Component {
static propTypes = {
todos: PropTypes.array.isRequired,
create: PropTypes.func.isRequired
}
render () {
return (
<div>
<List> <---------- using our presentational component
{this.props.todos.map((todo, key) =>
<Todo key={key} description={todo.description} />)}
</List>
<a href="#" onClick={this.props.create}>Add Todo</a>
</div>
);
}
}
const stateToProps = state => ({
todos: state.todos
});
const dispatchToProps = dispatch = ({
create: () => dispatch(createTodo())
});
export default connect(stateToProps, dispatchToProps)(TodoList);
DashboardView (componente de presentación)
import React, { Component } from ''react'';
import TodoList from ''containers/TodoList'';
export default class DashboardView extends Component {
render () {
return (
<div>
<TodoList />
</div>
);
}
};
Estoy tratando de refactorizar mi aplicación para separar los componentes de presentación y contenedor. Mis componentes de contenedor son solo los componentes de presentación envueltos en las llamadas connect()
de react-redux, que asignan los creadores de acción y estado a las propiedades de los componentes de presentación.
todo-list.container.js
import React, {Component} from ''react'';
import {connect} from ''react-redux'';
import {fetchTodos} from ''../actions/todo.actions'';
import TodoList from ''../components/todo-list.component'';
export default connect(({todo}) => ({state: {todo}}), {fetchTodos})(TodoList);
todo-list.component.jsx
import React, {Component} from ''react'';
import TodoContainer from ''../containers/todo.container'';
export default class TodoList extends Component {
componentDidMount () {
this.props.fetchTodos();
}
render () {
const todoState = this.props.state.todo;
return (
<ul className="list-unstyled todo-list">
{todoState.order.map(id => {
const todo = todoState.todos[id];
return <li key={todo.id}><TodoContainer todo={todo} /></li>;
})}
</ul>
);
}
};
todo.container.js
import React, {Component} from ''react'';
import {connect} from ''react-redux'';
import {createTodo, updateTodo, deleteTodo} from ''../actions/todo.actions'';
import Todo from ''../components/todo.component'';
export default connect(null, {createTodo, updateTodo, deleteTodo})(Todo);
todo.component.jsx
import React, {Component} from ''react'';
import ''../styles/todo.component.css'';
export default class Todo extends Component {
render () {
return (
<div className="todo">
{todo.description}
</div>
);
}
};
Lo que estoy tratando de averiguar es lo siguiente: sé que no debería incrustar el elemento <TodoContainer />
dentro de TodoList
porque TodoList
es un componente de presentación y solo debe anidar otros componentes de presentación dentro de él. Pero si lo sustituyo con solo un componente de presentación <Todo />
, entonces tengo que asignar cada prop de estado y prop de creador de acción en TodoListContainer
que el componente de Todo
necesitaría y pasarlos a todos de la cadena manualmente como props. Esto es algo que quiero evitar, por supuesto, especialmente si comienzo a anidar más niveles o comienzo dependiendo de más accesorios que vengan de Redux.
¿Me estoy acercando a esto correctamente? Parece que no debería intentar incrustar un componente contenedor dentro de un componente de presentación en general, porque si puedo separar los componentes de presentación de Redux, se vuelven más reutilizables. Al mismo tiempo, no sé cómo integrar un componente que requiera acceso al estado / envío de Redux dentro de cualquier otro componente que tenga marcado.