我正在跟踪来自https://github.com/reactjs/redux/tree/master/examples/todos
的Todo示例我做了一些小改动。我接受了todo中的更多字段。
{text, time, by}
并在表格中显示这些详细信息。
我想按时间订购此表。我不想要遵循此用例的redux模式。你问为什么!
对于像订购这样简单的事情,我不想在状态中添加它。我想在React state itself
内维护这些功能。由于VisibleTodoList是一个智能组件,其状态具有待机状态,我希望能够按照我喜欢的方式对其进行重新排序。
我的VisibleTodoList.js
const getVisibleTodos = (todos, filter) => {
switch (filter) {
case 'SHOW_ALL':
return todos
case 'SHOW_COMPLETED':
return todos.filter(t => t.completed)
case 'SHOW_ACTIVE':
return todos.filter(t => !t.completed)
default:
throw new Error('Unknown filter: ' + filter)
}
}
const orderTime = (todos) => {
console.log('inside order time!'); //Displays this. comes inside here.
return todos.filter(t => t.time > 20) //This gives me error!!
}
const mapStateToProps = (state) => ({
todos: getVisibleTodos(state.todos, state.visibilityFilter), // I do not want to add more things to the state. Want to keep it simple.
})
const mapDispatchToProps = ({
onTodoClick: toggleTodo,
onTimeClick: orderTime //My function defined above to returned filtered todos.
})
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
export default VisibleTodoList
TodoList.js
看起来像这样
const TodoList = ({ todos, persons, onTodoClick, completed, onTimeClick}) => (
<div>
<table>
<tbody>
<tr>
<th>Task Name</th>
<th
onClick={() => onTimeClick(todos)}
style={{
textDecoration: completed ? 'line-through' : 'none'
}}>Time</th>
<th>By person</th>
</tr>
{todos.map(todo =>
<Todo
key={todo.id}
{...todo}
/>
)}
</tbody>
</table>
</div>
)
我的todo.js看起来几乎一样
const Todo = ({ onClick, completed, text, time, by }) => (
<tr key={text}>
<td style={{
textDecoration: completed ? 'line-through' : 'none'}}>{text}</td>
<td>{time}</td>
<td>{by}</td>
</tr>
)
单击“时间”列时,我不断收到此错误
Actions must be plain objects. Use custom middleware for async actions.
我做错了什么?
我应该遵循什么模式来实现这一目标?没有偏离redux模式太多。我是否必须使用setState
要提供更多上下文,我希望拥有本地UI状态,而不是在redux存储中使用它。就像这里解释一样 Should you ever use this.setState() when using redux?
更新1 :我确实理解,因为orderTime
没有调度对象,所以它正在抱怨。但我更广泛的问题是,我必须做到实现相同的功能。我该怎么做?
如果我理解正确,我将不得不使用setState
来执行此操作。
答案 0 :(得分:0)
这是迄今为止我能提出的最佳解决方案!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MazeGenerator: MonoBehaviour {
public GameObject wallObjectRoot;
public GameObject wallObjectReference;
public float wallLength = 1.0f;
public int xSize = 5;
public int ySize = 5;
private Vector3 initialPos;
// Use this for initialization
void Start ()
{
if (wallObjectReference == null || wallObjectRoot == null){
Debug.LogError("WallHolder properties need to be assigned to MazeGenerator");
}
CreateWalls();
}
// Update is called once per frame
void Update () {
}
void CreateWalls()
{
initialPos = new Vector3((-xSize / 2) + wallLength / 2, (-ySize / 2) + wallLength / 2);
//For x axis
for (int i = 0; i < ySize; i++)
{
for (int j = 0; j <= xSize; j++)
{
Vector3 spawnPos = new Vector3(initialPos.x + (j * wallLength) - wallLength / 2, 0.0f, initialPos.z + (i * wallLength) - wallLength / 2);
GameObject wallObject = Instantiate(wallObjectReference, spawnPos, Quaternion.identity);
wallObject.transform.parent = wallObjectRoot.transform;
}
}
//for y axis
for (int i = 0; i <= ySize; i++)
{
for (int j = 0; j < xSize; j++)
{
Vector3 spawnPos = new Vector3(initialPos.x + (j * wallLength), 0.0f, initialPos.z + (i * wallLength) - wallLength);
GameObject wallObject = Instantiate(wallObjectReference, spawnPos, Quaternion.Euler(0.0f, 90.0f, 0.0f));
wallObject.transform.parent = wallObjectRoot.transform;
}
}
}
}
这是UI调整(排序,排序和其他操作),我们将其保持在React本地状态。这导致代码更清晰,因为我们的const getVisibleTodos = (todos, filter) => {
switch (filter) {
case 'WEIGHT_SORT':
return _.sortBy(todos, [function(o) { return o.time; }]);
default:
throw new Error('Unknown filter: ' + filter)
}
}
class TodoList extends React.Component {
state = { filter: 'SHOW_ALL' }
handleShow = filter => {
this.setState({ filter: 'WEIGHT_SORT' })
}
render(){
const filteredTodos = getVisibleTodos(todos, this.state.filter)
return (
<div>
<table>
<tbody>
<tr>
<th>Task Name</th>
<th
onClick={() => this.handleShow('SHOW_COMPLETED')}>Time</th>
<th>By person</th>
</tr>
{filteredTodos.map(todo =>
<Todo
key={todo.id}
{...todo}
onClick={() => this.props.onTodoClick(todo.id)}
/>
)}
</tbody>
</table>
</div>
)
}
}
很干净,并且不存储所有这些信息。
对建议/评论和更好的答案持开放态度!