ตอบสนอง + useState () + previousState

Sep 11 2020

ผมค่อนข้างใหม่เพื่อตอบสนองและมีปัญหาในการทำความเข้าใจ Hook useState - หรือมากขึ้นโดยเฉพาะด้านของpreviousState

useState Hook ปกติและอาจเป็นตัวอย่างที่พบบ่อยที่สุดมีลักษณะดังนี้:

import React, { useState} from 'react';

export default function CounterHooks({ initialCount }){
  const [count, setCount] = useState(initialCount);

  return (
    <div>
      <button onClick={() => setCount(count -1)}>-</button>
      <span>{count}</span>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  )
}

สิ่งที่ฉันเข้าใจจนถึงตอนนี้มีดังต่อไปนี้:

  • ฉันเรียกใช้ฟังก์ชัน useState () / Hook? และส่งผ่านอาร์กิวเมนต์ของสถานะเริ่มต้น (initialCount)
  • ฉันได้รับอาร์เรย์กลับมาซึ่งฉันทำลายลงในตัวแปรนับและ setCount ทันที (ซึ่งเป็นฟังก์ชัน)
  • ด้วย setCount () ฉันสามารถอัปเดตสถานะและดังนั้นตัวแปรการนับ

จนถึงตอนนี้ดีมากฉันคิดว่า ... ;)

บางครั้งฉันเห็นตัวอย่างตัวนับเดียวกันกับ prevState (prevCount) ซึ่งฉันไม่เข้าใจ:

<button onClick={() => setCount(prevCount => prevCount -1)}>-</button>

เกิดอะไรขึ้นที่นี่? ส่วนนี้ฉันไม่เข้าใจ ความคิดของฉันจนถึงตอนนี้:

  • ในกรณีนี้ฉันเข้าถึงค่าการนับก่อนหน้านี้
  • setCount คาดว่าจะมีฟังก์ชัน
  • setCount รันแบบอะซิงโครไนซ์แล้ว
  • ฟังก์ชั่นนี้มาจากไหน?
  • prevCount มาจากไหน?
  • เมื่อฉันเรียกใช้สิ่งนี้จะใส่อะไรลงใน prevCount?

คุณเข้าใจความสับสนของฉันหรือไม่? ฉันไม่แน่ใจว่าควรวางกรอบให้แตกต่างกันอย่างไร ...

ขอบคุณมากสำหรับความช่วยเหลือของคุณ.

คำตอบ

6 devserkan Sep 11 2020 at 19:15

ครั้งแรกของทั้งหมดที่คุณสามารถดูคำอธิบายอย่างเป็นทางการที่นี่

ในกรณีนี้ฉันเข้าถึงค่าการนับก่อนหน้านี้

คุณยังไม่ได้อย่างใดเข้าถึงมูลค่านับก่อนหน้านี้ หากคุณใช้การอัปเดตที่ใช้งานได้และมอบฟังก์ชันการโทรกลับให้กับตัวตั้งค่าจะส่งคืนสถานะก่อนหน้าให้คุณและคุณใช้ค่านี้ในฟังก์ชันเรียกกลับของคุณ

setCount คาดว่าจะมีฟังก์ชัน

เนื่องจากคุณมีฟังก์ชันจึงสามารถใช้งานได้

setCount รันแบบอะซิงโครไนซ์แล้ว

จริงๆแล้วไม่ ไม่ใช่ฟังก์ชันอะซิงโครนัส มันให้สถานะก่อนหน้าและคุณใช้มัน ตัวตั้งค่าสถานะไม่ใช่แบบอะซิงโครนัสการอัปเดตสถานะคือ

ฟังก์ชั่นนี้มาจากไหน?

prevCount มาจากไหน?

ตอบไปแล้ว.

เมื่อฉันเรียกใช้สิ่งนี้จะใส่อะไรลงใน prevCount?

คุณระบุสิ่งที่คุณต้องการตั้งค่าสถานะใหม่ที่นั่น ในตัวอย่างของคุณคุณต้องการเพิ่มทีละcount1 ดังนั้นคุณจึงระบุ+ 1

นี่คือคำอธิบายที่ไร้เดียงสาสำหรับตรรกะนี้ แค่ไร้เดียงสา ฉันกำลังเพิ่มสิ่งนี้เพื่อเป็นตัวอย่างตรรกะการเรียกกลับซึ่งไม่เกี่ยวข้องกับ React'ssetState.

let state = 5;

function setState(val) {
  if (typeof val === "function") {
    return val(state);
  }

  return val;
}

const stateWithFunctionalUpdate = setState(prev => prev + 1);
const stateWithNormalUpdate = setState(9);
console.log(stateWithFunctionalUpdate);
console.log(stateWithNormalUpdate);

บางทีตัวอย่างนี้อาจเหมาะสำหรับการเลียนแบบตรรกะการตั้งค่าสถานะของ React อีกครั้งเป็นเพียงวิธีการที่ไร้เดียงสา

let state = 5;

function setState(val) {
  if (typeof val === "function") {
    state = val(state);
  } else {
    state = val;
  }

}

setState(9);
setState(prev => prev + 1);

console.log("state", state);

มาดูการใช้งานจริงของuseState(โดยไม่ต้องพิมพ์):

export function useState(initialState) {
  return useReducer(
    basicStateReducer,
    // useReducer has a special case to support lazy useState initializers
    initialState
  );
}

ดีก็ใช้useReducerหลังม่าน มันตั้งค่าสถานะเริ่มต้นและใช้basicStateReducerซึ่งก็คือ:

function basicStateReducer(state, action) {
  return typeof action === "function" ? action(state) : action;
}

เช่นเดียวกับวิธีการที่ไร้เดียงสาของเรามองหาประเภทของactionและปฏิบัติตามนั้น สุดท้ายนี่คือuseReducer ผลตอบแทน :

return [workInProgressHook.memoizedState, dispatch];

ดังนั้นในตอนท้ายของวันถ้าเราจัดเตรียมฟังก์ชันให้useStateมันรับไปแล้วเรียกใช้ในสถานะของเราและคืนค่ากลับมา

1 VietDinh Sep 11 2020 at 19:10

นี่คือความคิดเห็นของฉันว่าฉันเข้าใจอย่างไร:

ในกรณีนี้ฉันเข้าถึงค่าการนับก่อนหน้านี้ -> setCount จะตรวจสอบพารามิเตอร์หากพารามิเตอร์เป็นการโทรกลับมันจะเรียกการโทรกลับนั้นและส่งผ่านสถานะก่อนหน้าสำหรับพารามิเตอร์ ผลการติดต่อกลับจะเป็นในสถานะถัดไป

setCount คาดว่าจะมีฟังก์ชัน -> ใช่แล้วฟังก์ชันจะจัดการกับตรรกะของคุณและส่งกลับสถานะถัดไป

setCount ขณะนี้ทำงานแบบอะซิงโครไนซ์ -> ฟังก์ชันนี้ซิงโครไนซ์ แต่หลังจากส่งคืนผลลัพธ์ hook สำหรับ setCount จะจัดส่งเหตุการณ์เพื่ออัปเดตสถานะถัดไป

ฟังก์ชั่นนี้มาจากไหน? -> คุณสามารถทำอะไรก็ได้ในฟังก์ชันตราบใดที่พารามิเตอร์จะเป็นสถานะปัจจุบันและส่งคืนสถานะถัดไป

prevCount มาจากไหน? -> จะถูกส่งผ่านเมื่อโทร setCount (ได้รับจากสถานะปัจจุบัน)

เมื่อฉันเรียกใช้สิ่งนี้จะใส่อะไรลงใน prevCount? -> สถานะปัจจุบันของ setCount

=> ตัวอย่างวิธีการส่งค่าหรือการเรียกกลับไปที่ setCount ที่นี่: useState hook, ฟังก์ชัน setState การเข้าถึงค่าสถานะก่อนหน้า