ค้นหาเว็บไซต์

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
  }
}