จะแสดงตัวบ่งชี้การโหลดในแอป React Redux ขณะดึงข้อมูลได้อย่างไร [ปิด]


107

ฉันยังใหม่กับ React / Redux ฉันใช้มิดเดิลแวร์ของ API ดึงข้อมูลในแอป Redux เพื่อประมวลผล API มันคือ ( redux-api-middleware ) ฉันคิดว่าเป็นวิธีที่ดีในการประมวลผลการดำเนินการ async api แต่ฉันพบบางกรณีที่ไม่สามารถแก้ไขได้ด้วยตัวเอง

ดังที่หน้าแรก ( Lifecycle ) กล่าวว่าวงจรการดึงข้อมูล API เริ่มต้นด้วยการส่งการดำเนินการ CALL_API ลงท้ายด้วยการส่งการดำเนินการ FSA

ดังนั้นกรณีแรกของฉันแสดง / ซ่อนตัวโหลดล่วงหน้าเมื่อดึง API มิดเดิลแวร์จะส่งการดำเนินการ FSA ที่จุดเริ่มต้นและส่งการดำเนินการ FSA ในตอนท้าย การดำเนินการทั้งสองได้รับโดยตัวลดซึ่งควรดำเนินการประมวลผลข้อมูลตามปกติเท่านั้น ไม่มีการใช้งาน UI ไม่มีการดำเนินการอีกต่อไป บางทีฉันควรบันทึกสถานะการประมวลผลในสถานะจากนั้นแสดงผลเมื่ออัปเดตร้านค้า

แต่จะทำอย่างไร? องค์ประกอบปฏิกิริยาไหลไปทั่วทั้งหน้า? เกิดอะไรขึ้นกับการอัปเดตร้านค้าจากการกระทำอื่น ๆ ฉันหมายความว่าพวกเขาเหมือนเหตุการณ์มากกว่าสถานะ!

ยิ่งไปกว่านั้นฉันควรทำอย่างไรเมื่อต้องใช้กล่องโต้ตอบยืนยันดั้งเดิมหรือกล่องโต้ตอบการแจ้งเตือนในแอป redux / react ควรวางการกระทำหรือตัวลดลงที่ไหน?

ด้วยความปรารถนาดี! ต้องการการตอบกลับ


1
ย้อนกลับการแก้ไขครั้งล่าสุดของคำถามนี้เนื่องจากเปลี่ยนประเด็นทั้งหมดของคำถามและคำตอบด้านล่าง
Gregg B

เหตุการณ์คือการเปลี่ยนสถานะ!
企业应用架构模式大师

ลองดูที่ questrar github.com/orar/questrar
61

คำตอบ:


152

ฉันหมายความว่าพวกเขาเหมือนเหตุการณ์มากกว่าสถานะ!

ฉันจะไม่พูดอย่างนั้น ฉันคิดว่าอินดิเคเตอร์การโหลดเป็นกรณีที่ยอดเยี่ยมของ UI ที่อธิบายได้ง่ายว่าเป็นฟังก์ชันของสถานะ: ในกรณีนี้คือตัวแปรบูลีน แม้ว่าคำตอบนี้จะถูกต้อง แต่ฉันก็อยากจะให้รหัสบางส่วนไปด้วย

ในasyncตัวอย่างใน Redux repo ตัวลดจะอัปเดตฟิลด์ที่เรียกว่าisFetching :

case REQUEST_POSTS:
  return Object.assign({}, state, {
    isFetching: true,
    didInvalidate: false
  })
case RECEIVE_POSTS:
  return Object.assign({}, state, {
    isFetching: false,
    didInvalidate: false,
    items: action.posts,
    lastUpdated: action.receivedAt

ส่วนประกอบใช้connect()จาก React Redux เพื่อสมัครสมาชิกสถานะของร้านค้าและส่งคืนisFetchingเป็นส่วนหนึ่งของmapStateToProps()ค่าส่งคืนดังนั้นจึงมีอยู่ในอุปกรณ์ประกอบฉากของส่วนประกอบที่เชื่อมต่อ:

function mapStateToProps(state) {
  const { selectedReddit, postsByReddit } = state
  const {
    isFetching,
    lastUpdated,
    items: posts
  } = postsByReddit[selectedReddit] || {
    isFetching: true,
    items: []
  }

  return {
    selectedReddit,
    posts,
    isFetching,
    lastUpdated
  }
}

สุดท้ายคอมโพเนนต์ใช้isFetchingเสาในrender()ฟังก์ชันเพื่อแสดงฉลาก "กำลังโหลด ... " (ซึ่งอาจเป็นสปินเนอร์แทน):

{isEmpty
  ? (isFetching ? <h2>Loading...</h2> : <h2>Empty.</h2>)
  : <div style={{ opacity: isFetching ? 0.5 : 1 }}>
      <Posts posts={posts} />
    </div>
}

ยิ่งไปกว่านั้นฉันควรทำอย่างไรเมื่อต้องใช้กล่องโต้ตอบยืนยันดั้งเดิมหรือกล่องโต้ตอบการแจ้งเตือนในแอป redux / react ควรวางการกระทำหรือตัวลดลงที่ไหน?

ผลข้างเคียงใด ๆ (และการแสดงกล่องโต้ตอบนั้นเป็นผลข้างเคียงอย่างแน่นอน) ไม่ได้อยู่ในตัวลด คิดว่าตัวลดขนาดเป็น "ผู้สร้างสถานะ" แบบแฝง พวกเขาไม่ได้ "ทำ" สิ่งต่างๆ

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

สำหรับทุกกฎมีข้อยกเว้น บางครั้งตรรกะผลข้างเคียงของคุณซับซ้อนมากจนคุณต้องการจับคู่กับประเภทการกระทำเฉพาะหรือกับตัวลดเฉพาะ ในกรณีนี้ให้ตรวจสอบโครงการขั้นสูงเช่นRedux SagaและRedux ห่วง ทำสิ่งนี้เฉพาะเมื่อคุณพอใจกับ vanilla Redux และมีปัญหาที่แท้จริงของผลข้างเคียงที่กระจัดกระจายซึ่งคุณต้องการให้จัดการได้ง่ายขึ้น


16
จะเกิดอะไรขึ้นถ้าฉันมีการดึงข้อมูลหลายรายการ ถ้าอย่างนั้นตัวแปรเดียวก็ไม่เพียงพอ
philk

1
@philk หากคุณมีการดึงข้อมูลหลายรายการคุณสามารถรวมกลุ่มไว้Promise.allในสัญญาเดียวจากนั้นส่งการดำเนินการเดียวสำหรับการดึงข้อมูลทั้งหมด หรือคุณต้องรักษาisFetchingตัวแปรหลายตัวในสถานะของคุณ
Sebastien Lorber

2
โปรดดูตัวอย่างที่ฉันเชื่อมโยงอย่างรอบคอบ มีisFetchingธงมากกว่าหนึ่งรายการ มันถูกตั้งค่าสำหรับทุกชุดของวัตถุที่ถูกดึงออกมา คุณสามารถใช้องค์ประกอบตัวลดเพื่อใช้งานได้
Dan Abramov

3
โปรดทราบว่าหากคำขอล้มเหลวและRECEIVE_POSTSไม่ถูกทริกเกอร์เครื่องหมายโหลดจะยังคงอยู่จนกว่าคุณจะสร้างระยะหมดเวลาบางอย่างเพื่อแสดงerror loadingข้อความ
James111

2
@TomiS - ฉันขึ้นบัญชีดำคุณสมบัติ isFetching ทั้งหมดของฉันอย่างชัดเจนจากสิ่งที่ฉันใช้อยู่
duhseekoh

22

คำตอบที่ยอดเยี่ยม Dan Abramov! เพียงแค่ต้องการเพิ่มว่าฉันทำมากหรือน้อยตรงนั้นในหนึ่งในแอพของฉัน (เก็บ isFetching เป็นบูลีน) และต้องทำให้มันเป็นจำนวนเต็ม (ซึ่งจะอ่านเป็นจำนวนคำขอที่ค้างอยู่) เพื่อรองรับหลาย ๆ พร้อมกัน คำขอ

ด้วยบูลีน:

คำขอ 1 เริ่มต้น -> สปินเนอร์บน -> คำขอ 2 เริ่มต้น -> คำขอ 1 สิ้นสุด -> สปินเนอร์ปิด -> ขอ 2 สิ้นสุด

ด้วยจำนวนเต็ม:

คำขอ 1 เริ่มต้น -> สปินเนอร์บน -> คำขอ 2 เริ่มต้น -> คำขอ 1 สิ้นสุด -> ขอ 2 สิ้นสุด -> สปินเนอร์ปิด

case REQUEST_POSTS:
  return Object.assign({}, state, {
    isFetching: state.isFetching + 1,
    didInvalidate: false
  })
case RECEIVE_POSTS:
  return Object.assign({}, state, {
    isFetching: state.isFetching - 1,
    didInvalidate: false,
    items: action.posts,
    lastUpdated: action.receivedAt

2
นี่เป็นเรื่องที่สมเหตุสมผล อย่างไรก็ตามบ่อยครั้งที่คุณต้องการจัดเก็บข้อมูลบางอย่างที่คุณดึงมานอกเหนือจากค่าสถานะ ณ จุดนี้คุณจะต้องมีวัตถุมากกว่าหนึ่งชิ้นที่มีisFetchingธง หากคุณดูตัวอย่างที่ฉันเชื่อมโยงอย่างใกล้ชิดคุณจะเห็นว่าไม่มีวัตถุชิ้นเดียวisFetchedแต่มีหลายชิ้น: หนึ่งรายการต่อ subreddit (ซึ่งเป็นสิ่งที่ดึงมาจากตัวอย่างนั้น)
Dan Abramov

2
โอ้. ใช่ฉันไม่ได้สังเกตเห็นสิ่งนั้น อย่างไรก็ตามในกรณีของฉันฉันมีรายการ isFetching ระดับโลกรายการเดียวในสถานะและรายการแคชที่เก็บข้อมูลที่ดึงมาและเพื่อจุดประสงค์ของฉันฉันสนใจแค่ว่ามีกิจกรรมเครือข่ายบางอย่างเกิดขึ้นไม่สำคัญว่าจะเกิดขึ้นเพื่ออะไร
Nuno Campos

4
เออ! ขึ้นอยู่กับว่าคุณต้องการแสดงตัวบ่งชี้การดึงข้อมูลในที่เดียวหรือหลายแห่งใน UI ในความเป็นจริงคุณสามารถรวมสองแนวทางและมีทั้งส่วนกลางfetchCounterสำหรับแถบความคืบหน้าบางส่วนที่ด้านบนของหน้าจอและisFetchingแฟล็กเฉพาะหลายรายการสำหรับรายการและเพจ
Dan Abramov

หากฉันมีคำขอ POST ในไฟล์มากกว่าหนึ่งไฟล์ฉันจะตั้งค่าสถานะของ isFetching เพื่อติดตามสถานะปัจจุบันได้อย่างไร
user989988

13

ฉันต้องการเพิ่มบางอย่าง ตัวอย่างโลกแห่งความเป็นจริงใช้ช่องisFetchingในร้านค้าเพื่อแสดงเมื่อมีการดึงคอลเลกชันของรายการ คอลเลกชันใด ๆ จะรวมอยู่ในตัวpaginationลดที่สามารถเชื่อมต่อกับส่วนประกอบของคุณเพื่อติดตามสถานะและแสดงว่าคอลเล็กชันกำลังโหลดอยู่หรือไม่

เกิดขึ้นกับฉันว่าฉันต้องการดึงรายละเอียดของเอนทิตีเฉพาะที่ไม่ตรงกับรูปแบบการแบ่งหน้า ฉันต้องการให้สถานะเป็นตัวแทนว่ามีการดึงรายละเอียดจากเซิร์ฟเวอร์หรือไม่ แต่ฉันไม่ต้องการให้มีตัวลดสำหรับสิ่งนั้น

ในการแก้ปัญหานี้ฉันได้เพิ่มตัวลดทั่วไปอื่นที่เรียกว่าfetching. ทำงานในลักษณะคล้ายกับการลดการแบ่งหน้าและมันเป็นความรับผิดชอบของเพียงเพื่อดู[entity, isFetching]ชุดของการกระทำและสร้างรัฐใหม่ที่มีคู่ ซึ่งช่วยให้connectตัวลดลงไปยังส่วนประกอบใด ๆ และเพื่อให้ทราบว่าแอปกำลังดึงข้อมูลไม่ใช่เฉพาะสำหรับคอลเลกชัน แต่สำหรับเอนทิตีเฉพาะหรือไม่


2
ขอบคุณสำหรับคำตอบ! การจัดการการโหลดของแต่ละรายการและสถานะของพวกเขานั้นไม่ค่อยมีใครพูดถึง!
Gilad Peleg

เมื่อฉันมีองค์ประกอบหนึ่งที่ขึ้นอยู่กับการกระทำของอีกวิธีที่รวดเร็วและสกปรกอยู่ใน mapStateToProps ของคุณรวมเข้าด้วยกันดังนี้: isFetching: posts.isFetching || comments.isFetching - ตอนนี้คุณสามารถบล็อกการโต้ตอบของผู้ใช้สำหรับคอมโพเนนต์ทั้งสองได้เมื่อมีการอัปเดตอย่างใดอย่างหนึ่ง
Philip Murphy

5

จนถึงตอนนี้ฉันไม่ได้เกิดคำถามนี้ขึ้น แต่เนื่องจากไม่มีการตอบรับฉันจึงโยนหมวกทิ้ง ผมเขียนเครื่องมือสำหรับงานมากนี้: การตอบสนอง-loader โรงงาน มันเกิดขึ้นมากกว่าวิธีแก้ปัญหาของ Abramov เล็กน้อย แต่เป็นแบบแยกส่วนและสะดวกกว่าเนื่องจากฉันไม่ต้องการคิดหลังจากเขียนมัน

มีสี่ชิ้นใหญ่:

  • รูปแบบโรงงาน: ช่วยให้คุณสามารถเรียกใช้ฟังก์ชันเดียวกันได้อย่างรวดเร็วเพื่อตั้งค่าว่าสถานะใดหมายถึง "กำลังโหลด" สำหรับส่วนประกอบของคุณและการดำเนินการใดที่จะจัดส่ง (ถือว่าคอมโพเนนต์มีหน้าที่เริ่มการทำงานที่รออยู่)const loaderWrapper = loaderFactory(actionsList, monitoredStates);
  • Wrapper: ส่วนประกอบที่โรงงานผลิตคือ "ส่วนประกอบลำดับที่สูงกว่า" (เช่นสิ่งที่connect()ส่งคืนใน Redux) เพื่อให้คุณสามารถเชื่อมต่อกับสิ่งที่มีอยู่ของคุณได้const LoadingChild = loaderWrapper(ChildComponent);
  • การโต้ตอบของ Action / Reducer: Wrapper จะตรวจสอบว่าตัวลดที่เสียบเข้ามีคำหลักที่บอกไม่ให้ส่งผ่านไปยังส่วนประกอบที่ต้องการข้อมูลหรือไม่ การดำเนินการที่ส่งโดย Wrapper คาดว่าจะสร้างคีย์เวิร์ดที่เกี่ยวข้อง (วิธีการจัดส่ง redux-api-middleware ACTION_SUCCESSและACTION_REQUESTเป็นต้น) (คุณสามารถส่งการกระทำไปที่อื่นและเพียงแค่ตรวจสอบจากกระดาษห่อหุ้มหากคุณต้องการ)
  • Throbber: องค์ประกอบที่คุณต้องการให้ปรากฏในขณะที่ข้อมูลส่วนประกอบของคุณขึ้นอยู่กับว่ายังไม่พร้อม ฉันเพิ่ม div ลงไปเล็กน้อยเพื่อให้คุณสามารถทดสอบได้โดยไม่ต้องใช้มัน

โมดูลนั้นไม่ขึ้นอยู่กับ redux-api-middleware แต่นั่นคือสิ่งที่ฉันใช้ด้วยดังนั้นนี่คือตัวอย่างโค้ดบางส่วนจาก README:

ส่วนประกอบที่มี Loader ห่อมัน:

import React from 'react';
import { myAsyncAction } from '../actions';
import loaderFactory from 'react-loader-factory';
import ChildComponent from './ChildComponent';

const actionsList = [myAsyncAction()];
const monitoredStates = ['ASYNC_REQUEST'];
const loaderWrapper = loaderFactory(actionsList, monitoredStates);

const LoadingChild = loaderWrapper(ChildComponent);

const containingComponent = props => {
  // Do whatever you need to do with your usual containing component 

  const childProps = { someProps: 'props' };

  return <LoadingChild { ...childProps } />;
}

ตัวลดสำหรับ Loader เพื่อตรวจสอบ (แม้ว่าคุณสามารถต่อสายได้ต่างกันหากต้องการ):

export function activeRequests(state = [], action) {
  const newState = state.slice();

  // regex that tests for an API action string ending with _REQUEST 
  const reqReg = new RegExp(/^[A-Z]+\_REQUEST$/g);
  // regex that tests for a API action string ending with _SUCCESS 
  const sucReg = new RegExp(/^[A-Z]+\_SUCCESS$/g);

  // if a _REQUEST comes in, add it to the activeRequests list 
  if (reqReg.test(action.type)) {
    newState.push(action.type);
  }

  // if a _SUCCESS comes in, delete its corresponding _REQUEST 
  if (sucReg.test(action.type)) {
    const reqType = action.type.split('_')[0].concat('_REQUEST');
    const deleteInd = state.indexOf(reqType);

    if (deleteInd !== -1) {
      newState.splice(deleteInd, 1);
    }
  }

  return newState;
}

ฉันคาดว่าในอนาคตอันใกล้ฉันจะเพิ่มสิ่งต่างๆเช่นการหมดเวลาและข้อผิดพลาดลงในโมดูล แต่รูปแบบจะไม่แตกต่างกันมาก


คำตอบสั้น ๆ สำหรับคำถามของคุณคือ:

  1. เชื่อมโยงการแสดงผลกับโค้ดการแสดงผล - ใช้ Wrapper รอบ ๆ ส่วนประกอบที่คุณต้องการแสดงผลด้วยข้อมูลเหมือนกับที่ฉันแสดงไว้ด้านบน
  2. เพิ่มตัวลดที่ทำให้สถานะของคำขอรอบ ๆ แอพที่คุณอาจสนใจว่าย่อยได้ง่ายดังนั้นคุณจึงไม่ต้องคิดหนักเกินไปว่าจะเกิดอะไรขึ้น
  3. เหตุการณ์และสถานะไม่แตกต่างกันจริงๆ
  4. สัญชาตญาณที่เหลือของคุณดูเหมือนจะถูกต้องสำหรับฉัน

4

ฉันเป็นคนเดียวที่คิดว่าตัวบ่งชี้การโหลดไม่ได้อยู่ในร้านค้า Redux หรือไม่? ฉันหมายความว่าฉันไม่คิดว่ามันเป็นส่วนหนึ่งของสถานะของแอปพลิเคชันต่อตัว ..

ตอนนี้ฉันทำงานกับ Angular2 และสิ่งที่ฉันทำคือฉันมีบริการ "กำลังโหลด" ซึ่งแสดงตัวบ่งชี้การโหลดที่แตกต่างกันผ่าน RxJS BehaviourSubjects .. ฉันเดาว่ากลไกเหมือนกันฉันแค่ไม่เก็บข้อมูลใน Redux

ผู้ใช้บริการ LoadingService เพียงสมัครเข้าร่วมกิจกรรมที่ต้องการฟัง ..

ผู้สร้างการดำเนินการ Redux ของฉันเรียก LoadingService เมื่อใดก็ตามที่จำเป็นต้องเปลี่ยนแปลง คอมโพเนนต์ UX สมัครรับข้อมูลที่สังเกตได้ ...


นี่คือเหตุผลที่ฉันชอบแนวคิดเรื่องการจัดเก็บซึ่งการกระทำทั้งหมดสามารถหยั่งเสียงได้ (ngrx และ redux-logic) บริการไม่ทำงานตรรกะซ้ำซ้อน - ทำงานได้ Nice reading
srghma

20
สวัสดีตรวจสอบย้อนหลังไปกว่าหนึ่งปีเพื่อบอกว่าฉันคิดผิดมาก แน่นอนว่าสถานะ UX อยู่ในสถานะแอปพลิเคชัน ฉันจะโง่แค่ไหน?
Spock

3

คุณสามารถเพิ่มผู้ฟังการเปลี่ยนแปลงในร้านค้าของคุณได้โดยใช้connect()จาก React Redux หรือstore.subscribe()วิธีระดับต่ำ คุณควรมีตัวบ่งชี้การโหลดในร้านค้าของคุณซึ่งตัวจัดการการเปลี่ยนแปลงร้านค้าสามารถตรวจสอบและอัปเดตสถานะส่วนประกอบได้ จากนั้นคอมโพเนนต์จะแสดงผลตัวโหลดล่วงหน้าหากจำเป็นขึ้นอยู่กับสถานะ

alertและconfirmไม่น่าจะเป็นปัญหา พวกเขากำลังบล็อกและแจ้งเตือนไม่ได้รับข้อมูลใด ๆ จากผู้ใช้ ด้วยconfirmคุณสามารถตั้งค่าสถานะตามสิ่งที่ผู้ใช้คลิกหากตัวเลือกของผู้ใช้ควรมีผลต่อการแสดงผลคอมโพเนนต์ หากไม่เป็นเช่นนั้นคุณสามารถจัดเก็บตัวเลือกเป็นตัวแปรสมาชิกองค์ประกอบเพื่อใช้ในภายหลังได้


เกี่ยวกับรหัสแจ้งเตือน / ยืนยันควรวางไว้ที่ใดการดำเนินการหรือตัวลดขนาด?
企业应用架构模式大师

ขึ้นอยู่กับว่าคุณต้องการทำอะไรกับพวกเขา แต่โดยสุจริตฉันใส่ไว้ในรหัสส่วนประกอบในกรณีส่วนใหญ่เนื่องจากเป็นส่วนหนึ่งของ UI ไม่ใช่ชั้นข้อมูล
MilošRašić

คอมโพเนนต์ UI บางตัวทำหน้าที่ทริกเกอร์เหตุการณ์ (เหตุการณ์เปลี่ยนสถานะ) แทนสถานะ เช่นภาพเคลื่อนไหวแสดง / ซ่อนตัวโหลดล่วงหน้า คุณดำเนินการอย่างไร?
企业应用架构模式大师

หากคุณต้องการใช้ส่วนประกอบที่ไม่ตอบสนองในแอปการตอบสนองของคุณวิธีแก้ปัญหาที่ใช้โดยทั่วไปคือการสร้างส่วนประกอบการตอบสนองของกระดาษห่อหุ้มจากนั้นใช้วิธีวงจรชีวิตเพื่อเริ่มต้นอัปเดตและทำลายอินสแตนซ์ของส่วนประกอบที่ไม่ตอบสนอง ส่วนประกอบดังกล่าวส่วนใหญ่ใช้ตัวยึดตำแหน่งใน DOM เพื่อเริ่มต้นและคุณจะแสดงผลเหล่านั้นในวิธีการแสดงผลขององค์ประกอบการตอบสนอง คุณสามารถอ่านเพิ่มเติมเกี่ยวกับวิธีวงจรชีวิตได้ที่นี่: facebook.github.io/react/docs/component-specs.html
MilošRašić

ฉันมีกรณี: พื้นที่แจ้งเตือนที่มุมบนขวาซึ่งมีข้อความแจ้งเตือนหนึ่งข้อความแต่ละข้อความจะปรากฏขึ้นแล้วหายไปหลังจากผ่านไป 5 วินาที คอมโพเนนต์นี้ไม่อยู่ในมุมมองเว็บที่จัดเตรียมโดยแอปโฮสต์เนทีฟ มีอินเทอร์เฟซ js บางอย่างเช่นaddNofication(message). อีกกรณีหนึ่งคือตัวโหลดล่วงหน้าซึ่งมีให้โดยโฮสต์เนทีฟแอปและเรียกใช้โดย javascript API ฉันเพิ่ม wrapper สำหรับ api เหล่านั้นในcomponentDidUpdateองค์ประกอบ React ฉันจะออกแบบอุปกรณ์ประกอบฉากหรือสถานะของส่วนประกอบนี้ได้อย่างไร
企业应用架构模式大师

3

เรามีการแจ้งเตือนสามประเภทในแอพของเราซึ่งทั้งหมดได้รับการออกแบบเป็นแง่มุม:

  1. ตัวบ่งชี้การโหลด (โมดอลหรือไม่ใช่โมดอลตามเสา)
  2. ป๊อปอัปข้อผิดพลาด (โมดอล)
  3. แถบแจ้งเตือน (ไม่ใช่โมดอลปิดเอง)

ทั้งสามอย่างนี้อยู่ที่ระดับบนสุดของแอปของเรา (หลัก) และต่อสายผ่าน Redux ดังที่แสดงในข้อมูลโค้ดด้านล่าง อุปกรณ์ประกอบฉากเหล่านี้ควบคุมการแสดงด้านที่เกี่ยวข้อง

ฉันได้ออกแบบพร็อกซีที่จัดการการเรียก API ทั้งหมดของเราดังนั้นข้อผิดพลาด isFetching และ (api) ทั้งหมดจะเป็นสื่อกลางกับ actionCreators ที่ฉันนำเข้าในพร็อกซี (นอกจากนี้ฉันยังใช้ webpack เพื่อแทรกการจำลองบริการสำรองสำหรับ dev เพื่อให้เราสามารถทำงานได้โดยไม่ต้องพึ่งพาเซิร์ฟเวอร์)

สถานที่อื่น ๆ ในแอปที่ต้องแจ้งประเภทใด ๆ ก็เพียงแค่นำเข้าการกระทำที่เหมาะสม แถบสแน็คบาร์และข้อผิดพลาดมีพารามิเตอร์สำหรับข้อความที่จะแสดง

@connect(
// map state to props
state => ({
    isFetching      :state.main.get('isFetching'),   // ProgressIndicator
    notification    :state.main.get('notification'), // Snackbar
    error           :state.main.get('error')         // ErrorPopup
}),
// mapDispatchToProps
(dispatch) => { return {
    actions: bindActionCreators(actionCreators, dispatch)
}}

) ส่งออกคลาสเริ่มต้น Main ขยาย React.Component {


ฉันกำลังดำเนินการตั้งค่าที่คล้ายกันโดยแสดงตัวโหลด / การแจ้งเตือน ฉันกำลังประสบปัญหา คุณมีส่วนสำคัญหรือตัวอย่างว่าคุณทำงานเหล่านี้ให้สำเร็จได้อย่างไร
Aymen

2

ฉันกำลังบันทึก URL เช่น ::

isFetching: {
    /api/posts/1: true,
    api/posts/3: false,
    api/search?q=322: true,
}

จากนั้นฉันก็มีตัวเลือกที่จำได้ (ผ่านการเลือกใหม่)

const getIsFetching = createSelector(
    state => state.isFetching,
    items => items => Object.keys(items).filter(item => items[item] === true).length > 0 ? true : false
);

เพื่อให้ URL ไม่ซ้ำกันในกรณีของ POST ฉันส่งตัวแปรบางตัวเป็นแบบสอบถาม

และที่ที่ฉันต้องการแสดงตัวบ่งชี้ฉันเพียงแค่ใช้ตัวแปร getFetchCount


1
คุณสามารถแทนที่Object.keys(items).filter(item => items[item] === true).length > 0 ? true : falseด้วยObject.keys(items).every(item => items[item])วิธีการ
Alexandre Annic

1
ฉันคิดว่าคุณหมายถึงsomeแทนที่จะเป็นeveryแต่ใช่มีหลายคนที่ไม่ต้องการการเปรียบเทียบในโซลูชันแรกที่เสนอ Object.entries(items).some(([url, fetching]) => fetching);
Rafael Porras Lucena
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.