Develop record
[React] Redux state 변경 본문
state 변경
1. store.js 에서 state 변경 함수 만들기
2. export
let user = createSlice({
name : 'user',
initialState : 'kim',
reducers : { // state 수정함수 만들기
함수명1(state){ // state : 기존 state
return '변경값' // 변경 state
},
함수명2(){
return
}
}
})
let user = createSlice({
name : 'user',
initialState : 'kim',
reducers : {
changeName(state){
return 'john'
}
}
})
// state 변경 함수 export 해서 다른 곳에서 사용하기 좋도록
export let {export 하고 싶은 함수명 : 함수명1, 함수명2 ...} = user.actions
// user.actions : state 변경 함수들이 그 자리에 출력 됨
export let {changeName} = user.actions
3. state 변경 함수 사용
4. import
5. useDispatch() 변수에 담아 사용
6. dispatch(state변경함수())
import { useDispatch, useSelector } from "react-redux";
import { changeName } from "../store";
//store.js 의 state 변경 함수 import
function Cart(){
let dispatch = useDispatch()
// useDispatch() : store.js 에 요청보내주는 함수 -> 변수에 담아 사용
return(
<button onClick={()=>{
dispatch(changeName())
//dispatch(state변경함수())로 사용
//함수를 실행하는 것이 아님 -> changeName() 실행해달라고 store.js에 요청
}}>+</button>
)
}
state : array / object 경우 변경
1. state.name = ''
2. return { name : '' }
3. 용도가 비슷한 함수 : parameter 빼서 parameter명.payload 해서 사용
4. 코드가 너무 길 경우 파일 따로 빼서 사용하기 (createSlice.js)
import { createSlice } from "@reduxjs/toolkit"
let user = createSlice({
name : 'user',
initialState : {name : 'kim', age : 20}, //문자 하나만 필요해도 object로 만드는 것이 수정에 용이
reducers : {
changeName(state){
state.name = 'park' //직접 수정해도 변경 됨
//return {name : 'park', age : 20}
},
// parameter 넣기 action : state 변경함수 -> action으로 parameter 이름을 많이 사용
changeAge(state, action){
state.age += action.payload
}
}
})
//changeAge(10) // cart.js에서 함수 사용시 ()안의 값이 a.payload에 대입 됨
//changeAge(100)
export let {changeName, changeAge} = user.actions
export default user;
// export -> store.js 에서 import 해서 사용
store.js
import user from './store/userSlice'
export default configureStore({
reducer: {
cart : cart.reducer,
user : user.reducer
}
})
cart.js
import { changeName,changeAge } from "../store/userSlice";
function Cart(){
let cart = useSelector((state)=>{return state})
let dispatch = useDispatch()
return(
<h6>{cart.user.name} {cart.user.age}의 장바구니</h6>
<button onClick={()=>{dispatch(changeAge(100))}}>버튼</button>
// changeAge() 안에 값이 action.payload 에 대입 -> 누를 때마다 +100 증가
)
}
1. 변경하기 버튼 클릭 시 각각의 수량 +1 씩 증가
2. detail/번호 url 에서 주문하기 버튼 클릭시 장바구니에 상품추가하기
store.js
import { act } from 'react-dom/test-utils';
import user from './store/userSlice'
import { configureStore, createSlice } from '@reduxjs/toolkit'
let cart = createSlice({
name : 'cart',
initialState : [
{id : 0, name : 'White and Black', count : 2},
{id : 2, name : 'Grey Yordan', count : 1}],
reducers: {
changeCount(state,action){
state[action.payload].count +=1;
// 조건에 맞는 index 값 찾기
// a : state 값
// let index = state.findIndex((a)=>{ return a.id === action.payload })
// a.id === action.payload : id 가 같을 때 count +
// state[index].count++
},
addCart(state,action){
let add = {
id : action.payload.id,
name : action.payload.title,
count : 1
}
console.log("action.payload")
console.log(add)
state.push(add)
},
delCart(state, action){
let index = state.findIndex((a)=>{return a.id === action.payload.id })
state.splice(index,1)
//delete state[index]
}
}
})
export let {changeCount, addCart} = cart.actions
export default configureStore({
reducer: {
cart : cart.reducer,
user : user.reducer
}
})
cart.js
import { Table } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import { changeName,changeAge } from "../store/userSlice";
import {changeCount} from "../store";
function Cart(){
let cart = useSelector((state)=>{return state.cart})
let user = useSelector((state)=>{return state.user})
let dispatch = useDispatch()
return(
<div>
<h6>{user.name} {user.age}의 장바구니</h6>
<button onClick={()=>{dispatch(changeAge(100))}}>버튼</button>
<Table>
<thead>
<tr>
<th>id</th>
<th>상품명</th>
<th>수량</th>
<th>변경하기</th>
</tr>
</thead>
<tbody>
{
cart.map(function(a,i){
return(
<tr key={i}>
<td>{a.id}</td>
<td>{a.name}</td>
<td>{a.count}</td>
<td>안녕</td>
<td>
<button onClick={()=>{
dispatch(changeCount(i))
}}>+</button>
</td>
<td>
<button onClick={()=>{
dispatch(delCart(a))
}}>삭제</button>
</td>
</tr>
)
})
}
</tbody>
</Table>
</div>
)
}
export default Cart;
detail.js
import { useEffect, useState } from "react";
import { Container, Row, Col } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import { useParams } from "react-router";
import styled from "styled-components";
import { addCart } from "../store";
function Detail(props){
let [count, setCount] = useState(0)
let [input, setInput] = useState("")
let [alert, setAlert] = useState(false)
let cart = useSelector((state)=>state.cart)
let dispatch = useDispatch()
console.log(cart);
useEffect(()=>{
var numberChk = /^[0-9]*$/;
if(!input.match(numberChk)){
setAlert(true)
}else{
setAlert(false)
}
},[input])
let{id} = useParams();
if(id >= props.shoes.length){
return <div>없는상품입니다.</div>
}
return(
<div>
<Container>
<button onClick={()=>{ setCount (count+1)}}>버튼{count}</button>
<Row>
<Col md={6}>
<img src={"https://codingapple1.github.io/shop/shoes"+(props.shoes[id].id+1)+".jpg"} width="80%"/>
<h4>{props.shoes[id].title}</h4>
<p>{props.shoes[id].content}</p>
<p>{props.shoes[id].price}원</p>
<button className="btn btn-danger" onClick={()=>{
dispatch(addCart(props.shoes[id]))
}}>주문하기</button>
</Col>
</Row>
<input type="text" onChange={(e)=>{setInput(e.target.value)}}></input>
{ alert && <div>숫자만 입력가능합니다</div>}
</Container>
</div>
)
}
export default Detail;
'Frontend > React' 카테고리의 다른 글
[React] memo (0) | 2024.03.31 |
---|---|
[React] react - query , lazy, suspend (0) | 2024.03.31 |
[React] Redux 셋팅 / state 만들기 (0) | 2024.03.26 |
[React] Context API (0) | 2024.03.26 |
[React] 애니메이션-transition (0) | 2024.03.25 |