คำขออาแจ็กซ์ควรทำที่ไหนในแอพ Flux


194

ฉันกำลังสร้างแอปพลิเคชัน react.js ด้วยสถาปัตยกรรมของฟลักซ์และฉันพยายามหาว่าควรจะทำคำขอข้อมูลจากเซิร์ฟเวอร์ที่ไหนและเมื่อใด มีตัวอย่างใด ๆ สำหรับสิ่งนี้หรือไม่ (ไม่ใช่แอพพลิเคชั่นที่ต้องทำ!)

คำตอบ:


127

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

class MyResourceDAO {
  get(id) {
    if (!this.promises[id]) {
      this.promises[id] = new Promise((resolve, reject) => {
        // ajax handling here...
      });
    } 
    return this.promises[id];
  }
}

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

ตัวอย่างเช่นส่วนประกอบอาจทำ:

getInitialState() {
  return { data: myStore.getSomeData(this.props.id) };
}

ร้านค้าจะมีวิธีดำเนินการบางทีอาจเป็นดังนี้:

class Store {
  getSomeData(id) {
    if (!this.cache[id]) {
      MyResurceDAO.get(id).then(this.updateFromServer);
      this.cache[id] = LOADING_TOKEN;
      // LOADING_TOKEN is a unique value of some kind
      // that the component can use to know that the
      // value is not yet available.
    }

    return this.cache[id];
  }

  updateFromServer(response) {
    fluxDispatcher.dispatch({
      type: "DATA_FROM_SERVER",
      payload: {id: response.id, data: response}
    });
  }

  // this handles the "DATA_FROM_SERVER" action
  handleDataFromServer(action) {
    this.cache[action.payload.id] = action.payload.data;
    this.emit("change"); // or whatever you do to re-render your app
  }
}

คุณเคยลองใส่คำมั่นสัญญาใน payloads หรือยัง ฉันพบว่ามันง่ายกว่าที่จะจัดการกับมากกว่าการฆ่าหลายการกระทำ
เซบาสเตียน Lorber

@SebastienLorber วาดขนาดใหญ่ที่จะฟลักซ์สำหรับผมที่จะทำให้การปรับปรุงรัฐทั้งหมดในเส้นทางรหัสซิงโครและชัดเจนเพียง แต่เป็นผลมาจากการดำเนินการยื้อดังนั้นฉันหลีกเลี่ยง asynchrony ภายในร้านค้า
Michelle Tilley

1
@ เฟเดริโกมันยังไม่ชัดเจนสำหรับฉันว่าโซลูชันที่ดีที่สุดคืออะไร ฉันกำลังทดลองกับกลยุทธ์นี้สำหรับการโหลดข้อมูลรวมกับการนับจำนวนคำขอ async ที่คงค้าง น่าเสียดายที่fluxถูกฉีดเข้าไปในร้านค้าหลังการก่อสร้างดังนั้นจึงไม่มีวิธีที่ยอดเยี่ยมในการดำเนินการตามวิธีการเตรียมใช้งาน คุณอาจพบความคิดดีๆจาก libs isomorophic flux libs; นี่เป็นสิ่งที่ Fluxxor v2 น่าจะสนับสนุนได้ดีกว่า อย่าลังเลที่จะส่งอีเมลฉันหากคุณต้องการที่จะพูดคุยเกี่ยวกับเรื่องนี้มากขึ้น
มิเชล Tilley

1
data: resultควรจะdata : dataใช่มั้ย resultไม่มี อาจดีกว่าที่จะเปลี่ยนชื่อพารามิเตอร์ข้อมูลเพื่อบรรจุข้อมูลหรืออะไรแบบนั้น
oligofren

2
ฉันพบว่ากระทู้เก่านี้มีประโยชน์มากโดยเฉพาะความคิดเห็นของ Bill Fisher และ Jing Chen นี่ใกล้เคียงกับสิ่งที่ @BinaryMuse เสนอกับความแตกต่างเล็กน้อยที่เกิดขึ้นในผู้สร้างแอคชั่น
phillipwei

37

Fluxxor มีตัวอย่างของการสื่อสารแบบ async กับ API

โพสต์บล็อกนี้ได้พูดคุยเกี่ยวกับมันและได้รับการแนะนำในบล็อกของ React


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

คำขอ API ควรทำในส่วนประกอบ JSX หรือไม่ ร้านค้า? สถานที่อื่น ๆ ?

การดำเนินการตามคำขอในร้านค้าหมายความว่าหาก 2 ร้านค้าต้องการข้อมูลเดียวกันสำหรับการดำเนินการที่กำหนดพวกเขาจะออกคำขอที่คล้ายกัน 2 รายการ (เว้นแต่คุณจะแนะนำการพึ่งพาระหว่างร้านค้าซึ่งฉันไม่ชอบ )

ในกรณีของฉันฉันพบว่ามีประโยชน์มากที่จะให้สัญญา Q เป็นส่วนของการกระทำเพราะ:

  • การกระทำของฉันไม่จำเป็นต้องเป็นแบบอนุกรม (ฉันไม่ได้เก็บบันทึกเหตุการณ์ฉันไม่ต้องการคุณลักษณะการเล่นซ้ำเหตุการณ์ของการจัดหากิจกรรม)
  • มันเอาความต้องการที่จะมีการกระทำที่แตกต่างกัน / เหตุการณ์ (คำขอยิง / คำขอเสร็จสมบูรณ์ / คำขอล้มเหลว) และต้องจับคู่พวกเขาโดยใช้รหัสความสัมพันธ์เมื่อคำขอสามารถเกิดขึ้นพร้อมกัน
  • อนุญาตให้ร้านค้าหลายแห่งรับฟังคำขอที่เสร็จสมบูรณ์โดยไม่ต้องแนะนำการพึ่งพาระหว่างร้านค้าใด ๆ (แต่อาจเป็นการดีกว่าที่จะแนะนำเลเยอร์แคช?)

อาแจ็กซ์ชั่วร้าย

ฉันคิดว่าอาแจ็กซ์จะใช้งานน้อยลงในอนาคตอันใกล้เพราะมันยากที่จะให้เหตุผล ทางที่ถูก? การพิจารณาอุปกรณ์เป็นส่วนหนึ่งของระบบกระจายฉันไม่รู้ว่าฉันเจอความคิดนี้ครั้งแรกที่ไหน (อาจเป็นในวิดีโอChris Granger ที่สร้างแรงบันดาลใจ )

ลองคิดดู ตอนนี้สำหรับความสามารถในการปรับขนาดเราใช้ระบบกระจายที่มีความสอดคล้องในที่สุดเป็นเครื่องมือเก็บข้อมูล (เพราะเราไม่สามารถเอาชนะทฤษฎีบท CAPและบ่อยครั้งที่เราต้องการให้มี) ระบบเหล่านี้ไม่ได้ทำการสำรวจความคิดเห็นของกันและกัน (ยกเว้นอาจจะเป็นฉันทามติการดำเนินการ) แต่ใช้โครงสร้างเช่น CRDT และบันทึกเหตุการณ์เพื่อให้สมาชิกทั้งหมดของระบบกระจายสอดคล้องกันในที่สุด (สมาชิกจะรวมกันเป็นข้อมูลเดียวกันให้เวลาเพียงพอ) .

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

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

ฉันคิดว่าเราควรสร้างแรงบันดาลใจให้ตัวเองว่าฐานข้อมูลทำงานกับสถาปัตยกรรมแอปพลิเคชันส่วนหน้าของเราอย่างไร สิ่งหนึ่งที่ควรสังเกตคือแอพเหล่านี้ไม่ได้ทำการร้องขอ POST และ PUT และ GET ajax เพื่อส่งข้อมูลให้กัน แต่ควรใช้บันทึกเหตุการณ์และ CRDT เพื่อให้แน่ใจว่ามีความสอดคล้องกันในที่สุด

ดังนั้นทำไมไม่ทำเช่นนั้นในส่วนหน้า? ขอให้สังเกตว่าแบ็กเอนด์กำลังเคลื่อนไปในทิศทางนั้นด้วยเครื่องมือเช่นคาฟคาที่มีผู้เล่นรายใหญ่นำมาใช้อย่างหนาแน่น สิ่งนี้เกี่ยวข้องกับการจัดหากิจกรรม / CQRS / DDD ด้วยเช่นกัน

ตรวจสอบบทความที่ยอดเยี่ยมเหล่านี้จากผู้เขียน Kafka เพื่อโน้มน้าวตัวเอง:

บางทีเราสามารถเริ่มต้นด้วยการส่งคำสั่งไปยังเซิร์ฟเวอร์และรับกระแสเหตุการณ์เซิร์ฟเวอร์ (ผ่าน websockets สำหรับตัวอย่าง) แทนการยิงคำขอ Ajax

ฉันไม่เคยพอใจกับคำขอของ Ajax มาก่อน ในขณะที่เราตอบสนองผู้พัฒนาโปรแกรมมักจะทำงานเป็นโปรแกรมเมอร์ ฉันคิดว่ามันยากที่จะให้เหตุผลเกี่ยวกับข้อมูลท้องถิ่นที่ควรจะเป็น "แหล่งที่มาของความจริง" ของแอปพลิเคชั่นส่วนหน้าของคุณในขณะที่แหล่งที่แท้จริงของความเป็นจริงนั้นอยู่บนฐานข้อมูลเซิร์ฟเวอร์และแหล่งที่มา เมื่อคุณได้รับมันและจะไม่มาบรรจบกันกับแหล่งที่แท้จริงของค่าความจริงเว้นแต่คุณจะกดปุ่ม Refresh บางอย่าง ... วิศวกรรมนี้หรือไม่

อย่างไรก็ตามมันก็ยังยากที่จะออกแบบสิ่งนี้ด้วยเหตุผลบางอย่างที่ชัดเจน:

  • มือถือ / เบราว์เซอร์ไคลเอ็นต์ของคุณมีทรัพยากรที่ จำกัด และไม่สามารถจัดเก็บข้อมูลทั้งหมดในพื้นที่ได้ (บางครั้งอาจต้องการการโพลด้วย ajax ที่ร้องขอเนื้อหาจำนวนมาก)
  • ลูกค้าของคุณไม่ควรเห็นข้อมูลทั้งหมดของระบบกระจายดังนั้นจึงจำเป็นต้องมีการกรองเหตุการณ์ที่ได้รับด้วยเหตุผลด้านความปลอดภัย

3
คุณสามารถให้ตัวอย่างของการใช้ Q สัญญากับการกระทำได้หรือไม่?
แมตต์เรดฟอกซ์ดันแคน

@MattFoxxDuncan ไม่แน่ใจว่ามันเป็นความคิดที่ดีเพราะมันทำให้ "event log" ไม่สามารถบันทึกได้และทำให้การอัปเดตร้านค้าแบบอะซิงโครนัสกับการกระทำที่ถูกไล่ออกดังนั้นมันจึงมีข้อเสียอยู่บ้าง ลดสำเร็จรูป ด้วย Fluxxor คุณสามารถทำสิ่งที่ต้องการthis.dispatch("LOAD_DATA", {dataPromise: yourPromiseHere});
Sebastien Lorber

ไม่เห็นด้วยอย่างยิ่งเกี่ยวกับอาร์กิวเมนต์ AJAX ของคุณ ในความเป็นจริงมันน่ารำคาญมากที่จะอ่าน คุณอ่านคำพูดของคุณ? ลองนึกถึงร้านค้าเกมแอพที่ทำเงินอย่างจริงจัง - ทั้งหมดต้องใช้การเรียกเซิร์ฟเวอร์ API และ AJAX .. ดูที่ Firebase ถ้าคุณต้องการ "serverless" หรืออะไรทำนองนั้น แต่ AJAX อยู่ที่นี่เพื่อบอกว่าฉันหวังว่าอย่างน้อยก็ไม่มีใครเห็นด้วย ตรรกะของคุณ
TheBlackBenzKid

@TheBlackBenzKid ฉันไม่ได้บอกว่า Ajax จะหายไปอย่างสิ้นเชิงในปีนี้ (และต้องแน่ใจว่าฉันยังคงสร้างเว็บไซต์บน ajax ร้องขอในขณะนี้เป็น CTO ของการเริ่มต้น) แต่ฉันบอกว่ามันจะหายไปเพราะ มันไม่ได้เป็นโปรโตคอลที่ดีพอที่จะจัดการกับความมั่นคงในที่สุดซึ่งค่อนข้างต้องสตรีมมิ่งและไม่ได้ทำการสำรวจและในที่สุดความสอดคล้องคือสิ่งที่อนุญาตให้แอปทำงานแบบออฟไลน์ได้อย่างน่าเชื่อถือ (ใช่คุณสามารถแฮ็คบางสิ่งด้วย Localstorage แอปของคุณง่ายมาก) ปัญหาไม่ได้แคช แต่จะทำให้แคชนั้นใช้การไม่ได้
Sebastien Lorber

@TheBlackBenzKid โมเดลที่อยู่เบื้องหลัง Firebase, Meteor ฯลฯ ไม่ดีพอ คุณรู้หรือไม่ว่าระบบเหล่านี้จัดการการเขียนพร้อมกันได้อย่างไร last-write-win แทนที่จะเป็นกลยุทธ์ความสอดคล้อง / การรวมที่เป็นสาเหตุ? คุณสามารถที่จะเอาชนะงานเพื่อนร่วมงานของคุณในแอปเมื่อทั้งคู่กำลังทำงานกับการเชื่อมต่อที่ไม่น่าเชื่อถือหรือไม่? นอกจากนี้โปรดทราบว่าระบบเหล่านี้มีแนวโน้มที่จะเป็นคู่กับโมเดลท้องถิ่นและเซิร์ฟเวอร์ คุณรู้หรือไม่ว่าแอพพลิเคชั่นการทำงานร่วมกันที่มีความซับซ้อนซับซ้อนทำงานออฟไลน์ได้อย่างสมบูรณ์แบบประกาศว่าเป็นผู้ใช้ Firebase ที่พอใจหรือไม่? ฉันไม่
Sebastien Lorber

20

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


9
คุณช่วยอธิบายรายละเอียดเพิ่มเติมได้มั้ย สมมติว่าฉันต้องทำการโหลดข้อมูลเริ่มต้นจากเซิร์ฟเวอร์ ในมุมมองตัวควบคุมฉันเริ่มต้นการดำเนินการ INIT และ Store เริ่มต้นมันเป็นการเริ่มต้น async ที่สะท้อนถึงการกระทำนี้ ตอนนี้ฉันจะไปกับความคิดที่ว่าเมื่อร้านค้าดึงข้อมูลมันก็จะปล่อยการเปลี่ยนแปลง แต่ไม่ได้เริ่มการกระทำ ดังนั้นการเปลี่ยนแปลงหลังจากการเริ่มต้นจะบอกมุมมองว่าพวกเขาสามารถรับข้อมูลจากร้านค้าได้ ทำไมไม่จำเป็นต้องปล่อยการเปลี่ยนแปลงเมื่อโหลดสำเร็จ แต่เริ่มต้นการกระทำอื่น! ขอบคุณ
Jim-Y

Fisherwebdev เกี่ยวกับร้านค้าที่เรียกใช้ข้อมูลโดยการทำเช่นนั้นคุณไม่ทำลายกระบวนทัศน์ของ Flux เพียง 2 วิธีที่เหมาะสมที่ฉันสามารถนึกถึงในการโทรหาข้อมูลโดยใช้: 1. ใช้คลาส bootstrap โดยใช้ Actions เพื่อโหลดข้อมูล 2 มุมมองใช้การดำเนินการเพื่อโหลดข้อมูลอีกครั้ง
Yotam

4
การโทรหาข้อมูลนั้นไม่เหมือนกับการรับข้อมูล @ Jim-Y: คุณควรปล่อยเท่านั้นเมื่อข้อมูลในร้านมีการเปลี่ยนแปลงจริง Yotam: ไม่การเรียกใช้ข้อมูลในร้านไม่ทำลายกระบวนทัศน์ ข้อมูลควรได้รับจากการกระทำเท่านั้นเพื่อให้ร้านค้าทั้งหมดอาจได้รับแจ้งข้อมูลใหม่ใด ๆ ที่เข้ามาในแอปพลิเคชัน ดังนั้นเราจึงสามารถเรียกใช้ข้อมูลในร้านค้าได้ แต่เมื่อการตอบกลับกลับมาเราจำเป็นต้องสร้างการกระทำใหม่แทนที่จะจัดการกับมันโดยตรง สิ่งนี้ทำให้แอพพลิเคชั่นมีความยืดหยุ่นและยืดหยุ่นต่อการพัฒนาคุณสมบัติใหม่
fisherwebdev

2

ฉันได้ใช้ตัวอย่างเช่นไบนารี Muse จากตัวอย่าง Ajax Fluxxor นี่คือตัวอย่างง่ายๆของฉันโดยใช้วิธีการเดียวกัน

ฉันมีความเรียบง่ายผลิตภัณฑ์จัดเก็บบางการกระทำของผลิตภัณฑ์และการควบคุมมุมมององค์ประกอบซึ่งมีส่วนประกอบย่อยที่ตอบสนองทุกการเปลี่ยนแปลงที่เกิดขึ้นกับการจัดเก็บสินค้า ยกตัวอย่างเช่นผลิตภัณฑ์เลื่อน , สินค้ารายการและสินค้าที่มีการค้นหาชิ้นส่วน

ลูกค้าผลิตภัณฑ์ปลอม

นี่คือไคลเอนต์ปลอมซึ่งคุณสามารถทดแทนการโทรหาผลิตภัณฑ์ที่ส่งคืนปลายทางจริง

var ProductClient = {

  load: function(success, failure) {
    setTimeout(function() {
      var ITEMS = require('../data/product-data.js');
      success(ITEMS);
    }, 1000);
  }    
};

module.exports = ProductClient;

ร้านค้าผลิตภัณฑ์

นี่คือ Product Store เห็นได้ชัดว่านี่เป็นร้านค้าที่น้อยมาก

var Fluxxor = require("fluxxor");

var store = Fluxxor.createStore({

  initialize: function(options) {

    this.productItems = [];

    this.bindActions(
      constants.LOAD_PRODUCTS_SUCCESS, this.onLoadSuccess,
      constants.LOAD_PRODUCTS_FAIL, this.onLoadFail
    );
  },

  onLoadSuccess: function(data) {    
    for(var i = 0; i < data.products.length; i++){
      this.productItems.push(data.products[i]);
    }    
    this.emit("change");
  },

  onLoadFail: function(error) {
    console.log(error);    
    this.emit("change");
  },    

  getState: function() {
    return {
      productItems: this.productItems
    };
  }
});

module.exports = store;

ตอนนี้การกระทำของผลิตภัณฑ์ซึ่งทำให้การร้องขอ AJAX และประสบความสำเร็จในการดำเนินการ LOAD_PRODUCTS_SUCCESS การดำเนินการส่งคืนผลิตภัณฑ์ไปที่ร้าน

การทำงานของผลิตภัณฑ์

var ProductClient = require("../fake-clients/product-client");

var actions = {

  loadProducts: function() {

    ProductClient.load(function(products) {
      this.dispatch(constants.LOAD_PRODUCTS_SUCCESS, {products: products});
    }.bind(this), function(error) {
      this.dispatch(constants.LOAD_PRODUCTS_FAIL, {error: error});
    }.bind(this));
  }    

};

module.exports = actions;

ดังนั้นการโทรthis.getFlux().actions.productActions.loadProducts()จากองค์ประกอบใด ๆ ที่ฟังร้านนี้จะโหลดผลิตภัณฑ์

คุณสามารถจินตนาการว่ามีการกระทำที่แตกต่างกันซึ่งจะตอบสนองต่อการโต้ตอบของผู้ใช้เช่นaddProduct(id) removeProduct(id)อื่น ๆ ... ตามรูปแบบเดียวกัน

หวังว่าตัวอย่างจะช่วยได้นิดหน่อยเนื่องจากฉันพบว่ามันใช้ยากเล็กน้อย แต่ก็ช่วยให้ร้านค้าของฉันซิงโครนัสได้ 100%


2

ฉันตอบคำถามที่เกี่ยวข้องที่นี่: วิธีจัดการสาย api ซ้อนกันในฟลักซ์

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

Bill Fisher ผู้สร้าง Flux https://stackoverflow.com/a/26581808/4258088

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

ร้านค้าควรรับผิดชอบในการรวบรวม / ดึงข้อมูลที่จำเป็นทั้งหมด สิ่งสำคัญคือให้สังเกตว่าหลังจากที่ร้านค้าร้องขอข้อมูลและรับการตอบกลับแล้วควรเรียกการกระทำด้วยข้อมูลที่นำกลับมาใช้ซึ่งตรงข้ามกับที่จัดเก็บ / บันทึกการตอบกลับโดยตรง

ร้านค้าอาจมีลักษณะเช่นนี้:

class DataStore {
  constructor() {
    this.data = [];

    this.bindListeners({
      handleDataNeeded: Action.DATA_NEEDED,
      handleNewData: Action.NEW_DATA
    });
  }

  handleDataNeeded(id) {
    if(neededDataNotThereYet){
      api.data.fetch(id, (err, res) => {
        //Code
        if(success){
          Action.newData(payLoad);
        }
      }
    }
  }

  handleNewData(data) {
    //code that saves data and emit change
  }
}

0

นี่คือสิ่งที่ฉันใช้ในเรื่องนี้: http://www.thedreaming.org/2015/03/14/react-ajax/

หวังว่าจะช่วย :)


8
downvote ตามแนวทาง การวางคำตอบลงบนไซต์ภายนอกทำให้ไซต์นี้มีประโยชน์น้อยลงและใช้สำหรับคำตอบที่มีคุณภาพต่ำลงลดประโยชน์ของไซต์ URL ภายนอกอาจแบ่งตามเวลาเช่นกัน downvote ไม่ได้พูดอะไรเกี่ยวกับประโยชน์ของบทความซึ่งโดยวิธีเป็นสิ่งที่ดีมาก :)
oligofren

2
โพสต์ที่ดี แต่การเพิ่มข้อสรุปสั้น ๆ เกี่ยวกับข้อดี / ข้อเสียของแต่ละวิธีจะช่วยให้คุณได้ upvotes ดังนั้นเราไม่จำเป็นต้องคลิกลิงก์เพื่อรับส่วนสำคัญของคำตอบของคุณ
Cory House
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.