如何在react.js应用程序中集成redux



当我尝试用函数代码应用redux_react时我对.subscribe((有问题它在每次状态更新时运行多次=(以前所有更新的计数+1(如何只重新渲染一次UI。。每个状态更新

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- Redux -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.2.0/redux.min.js" integrity="sha512-1/8Tj23BRrWnKZXeBruk6wTnsMJbi/lJsk9bsRgVwb6j5q39n0A00gFjbCTaDo5l5XrPVv4DZXftrJExhRF/Ug==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- react & react-dom -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<!-- Babel: transpiles JSX code into Common JS - that browser can understand -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<!-- Babel JSX code -->
<script type="text/babel">
// =============================== Redux (State management) =============================================
// action types
const [ADD_TODO, REMOVE_TODO, TOGGLE_TODO] = ["ADD_TODO", "REMOVE_TODO", "TOGGLE_TODO"]
const [ADD_GOAL] = ["ADD_GOAL"]
// action creators
const addTodo = todo => ({
type: ADD_TODO,
todo
})
const removeTodo = id => ({
type: REMOVE_TODO,
id
})
const toggleTodo = id => ({
type: TOGGLE_TODO,
id
})
const addGoal = goal => ({
type: ADD_GOAL,
goal
})
// Reducers
const todosReducer = (state=[], action) => {
switch (action.type) {
case ADD_TODO:
return [...state, action.todo]
case REMOVE_TODO:
return state.filter((s) => s.id !== action.id)
case TOGGLE_TODO:
return state.map((s) => (s.id == action.id)? {...s, complete: !s.complete} : s)
default:
return state
}
}
const goalsReducer = (state=[], action) => {
switch (action.type) {
case ADD_GOAL:
return [...state, action.goal]
default:
return state
}
}

// Redux Store
const store = Redux.createStore(
// Root Reducer
Redux.combineReducers({
todos: todosReducer,
goals: goalsReducer
})
)


// =============================== React App =============================================
// Components
const List = ({items, removeItem, toggle}) => {
return (
<ul>
{
items.map((itm) =>
<li key={itm.id}>
<span id={itm.id} onClick={(toggle)? toggle : null}  style={{textDecoration: (itm.complete)? 'line-through' : ''}}>
{itm.text}
</span>
<button id={itm.id} onClick={removeItem}> X </button>
</li>
)
}
</ul>
)
}
const Todos = ({items}) => {
const newTodoInput = React.useRef()
// add new
const handleAddTodo = () => {
const newTodo = newTodoInput.current
// Redux <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// dispatch the addTodo action --> to update Redux State
// ** No need to lift-up handleAddTodo() to all parents :)
store.dispatch(
addTodo({
id: (new Date()).getTime().toString(36),
text: newTodo.value,
complete: false
})
)
newTodo.value = ""
}
// remove
const handleRemoveTodo = (e) => {
store.dispatch(removeTodo(e.target.id))
}
// toggle
const handleToggle = (e) => {
store.dispatch(toggleTodo(e.target.id))
}
return (
<div>
<h3>My Todos:</h3>
<div>
<input type="text" placeholder="new todo ..." ref={newTodoInput} />
<button onClick={handleAddTodo}>Save</button>
</div>
<List items={items} removeItem={handleRemoveTodo} toggle={handleToggle} />
</div>
)
}
const Goals = ({items}) => {
return (
<div>
<h3>My Goals:</h3>
<List items={items} />
</div>
)
}
const App = ({store}) => {
const [todos, setTodos] = React.useState([])
const [goals, setGoals] = React.useState([])
// Redux <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
store.subscribe(() => {
console.log(store.getState())
const newState = store.getState()
setTodos(newState.todos)
setGoals(newState.goals)
})
return (
<div>
<Todos items={todos} />
<Goals items={goals} />
</div>
)
}

// Root
const root = ReactDOM.createRoot(document.getElementById("app"))
root.render(
<App store={store} />
)
</script>
</body>
</html>

我如何在不订阅所有以前的更新的情况下进行状态更新

您可以避免使用subscribe和react,以下是推荐的方法:

您可以将redux与react挂钩一起使用,以避免使用subscribe

要在状态更改时跟踪冗余更新,可以使用为制作的useSelector

然后你避免使用subscribe来改变你的状态,使用Selector为你做

不要忘记使用react-redux中的Provider

以下是的一个小例子

const Goals = () => {
const items = useSelector(goalsSelector)
return (
<div>
<h3>My Goals:</h3>
<List items={items} />
</div>
)
}
const App = ({store}) => {
return (
<Provider store={store}>
<div>
<Todos />
<Goals />
</div>
</Provider>
)
}

如果您仍然想在react函数组件内订阅,则必须使用useEffect

对于每个渲染器上的当前实现,您可以再次订阅redux。

在这里,您只在组件安装时订阅,然后在卸载时取消订阅

const App = ({store}) => {
const [todos, setTodos] = React.useState([])
const [goals, setGoals] = React.useState([])
// Redux <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
React.useEffect(() => {
const unsubscribe = store.subscribe(() => {
console.log(store.getState())
const newState = store.getState()
setTodos(newState.todos)
setGoals(newState.goals)
})
return unsubscribe;
}, [])
return (
<div>
<Todos items={todos} />
<Goals items={goals} />
</div>
)
}

使用useSelectorconnect()API从redux状态读取,而不是手动订阅存储。CCD_ 9和CCD_。

相关内容

  • 没有找到相关文章

最新更新