reactjs - ส่งอาร์กิวเมนต์ไปยังรีดิวเซอร์?
ฉันมีการดำเนินการที่กำหนดไว้ดังนี้ในตัวสร้าง:
export const actionCreators = {
submitlink: (url: string) => <SubmitLinkAction>{ type: 'SUBMIT_LINK' }
}
ในคอมโพเนนต์ที่เรียกมัน:
public render() {
return <div>
<div>{this.props.url}</div>
<button onClick={() =>
{
this.props.submitlink("google.com");
}}>submit</button>
</div>
}
ดังนั้นฉันกำลังพยายามหาวิธีว่าในฟังก์ชันรีดิวเซอร์ฉันสามารถดึงอาร์กิวเมนต์ที่ถูกส่งเข้ามาได้อย่างไร? นี่คือรูปลักษณ์ของรีดิวเซอร์:
export const reducer: Reducer<SubmitLinkState> = (state: SubmitLinkState, action: KnownAction) => {...}
อย่างไรก็ตาม ถ้านี่ไม่ใช่ขั้นตอนการทำงานที่ถูกต้อง ฉันควรทำอย่างไร? เป้าหมายสุดท้ายคือมีช่องข้อความและปุ่มส่งที่เมื่อกดแล้วจะส่งเนื้อหาของช่องข้อความนั้นไปยัง reducer
คำตอบ #1
คุณสามารถส่ง URL เป็นพารามิเตอร์ของการกระทำได้ดังนี้
export const actionCreators = {
submitlink: (url: string) => <SubmitLinkAction>{ type: 'SUBMIT_LINK', url}
}
แล้วจากนั้นในรีดิวเซอร์เข้าถึงมันเป็น action.url
export const reducer: Reducer<SubmitLinkState> = (state: SubmitLinkState, action: KnownAction) => {
...
console.log(action.url);
}
คำตอบ #2
คุณสามารถใช้ข้อมูลการกระทำเพื่อส่งตัวแปรไปยังตัวลดค่าได้
สมมติว่าคุณจำเป็นต้องสร้างคอมโพเนนต์ 1 ตัวเพื่อจัดการตรรกะการเรนเดอร์ฝั่งเซิร์ฟเวอร์ของตารางข้อมูลทั้งหมดของคุณ:
คุณสามารถกำหนดสถานะเริ่มต้นแบบนี้ได้:
// ** Initial State
const initialState = {
rowsPerPage: 2,
totalItems: 0,
rows: [],
totalPages: 0,
currentPage: 0,
columns: [],
selectedClient: false,
isLoading: false,
searchValue: '',
apiURL: `${process.env.REACT_APP_BACKEND_API_ADDR}test`,
extraRequestParams: {}
}
จากนั้นคุณสามารถกำหนดการกระทำ (Action) เพื่ออัปเดตข้อมูลในตารางได้แบบนี้ สังเกตว่าเรากำลังส่งชื่อ Store เป็นพารามิเตอร์เพื่อให้เราอัปเดตตารางข้อมูลที่ถูกต้อง (เนื่องจากคุณอาจมีหลายตารางข้อมูลในแอปของคุณ)
import axios from 'axios'
//Default Table Actions
export const updateRows = ({ storeName }) => {
return async (dispatch, getState) => {
dispatch({
storeName,
type: `${storeName}-ENABLE_LOADING`
})
const { rowsPerPage, currentPage, selectedClient, searchValue, extraRequestParams } =
getState()[storeName]
const response = await axios.get(getState()[storeName].apiURL, {
params: {
rowsPerPage,
currentPage,
selectedClient,
searchValue,
extraRequestParams
}
})
dispatch({
storeName,
type: `${storeName}-UPDATE_ROWS`,
data: response.data
})
dispatch({
storeName,
type: `${storeName}-DISABLE_LOADING`
})
}
}
หลังจากนั้นคุณอาจมี Reducer แบบนี้:
const DatatablesReducer = (state = initialState, action) => {
switch (action.type) {
case `${action.storeName}-UPDATE_ROWS`:
return {
...state,
...action.data
}
case `${action.storeName}-ENABLE_LOADING`:
return {
...state,
isLoading: true
}
case `${action.storeName}-DISABLE_LOADING`:
return {
...state,
isLoading: false
}
case `${action.storeName}-CHANGE_PAGE`:
return {
...state,
currentPage: action.data
}
case `${action.storeName}-CHANGE_ROWS_PER_PAGE`:
return {
...state,
rowsPerPage: action.data
}
case `${action.storeName}-CHANGE_SEARCH_VALUE`:
return {
...state,
searchValue: action.data
}
case `${action.storeName}-CHANGE_APIURL_VALUE`:
return {
...state,
apiURL: action.data
}
case `${action.storeName}-CHANGE_EXTRAREQUEST_PARAMS`:
return {
...state,
extraRequestParams: action.data
}
default:
return state
}
}
