Back to Question Center
0

เกี่ยวกับ API แบบอะซิงโครนัสในการตอบสนองต่อเซิร์ฟเวอร์            เกี่ยวกับ API แบบอะซิงโครนัสในหัวข้อ ReactRelated ที่แสดงโดยเซิร์ฟเวอร์: ES6Ral Semalt

1 answers:
เกี่ยวกับ API แบบอะซิงโครนัสในปฏิกิริยาตอบสนองของเซิร์ฟเวอร์

สำหรับการเปิดตัวเชิงลึกเกี่ยวกับ React ที่มีคุณภาพสูงคุณจะไม่สามารถไปยัง Wes Bos ที่เป็นนักพัฒนาเต็มรูปแบบของแคนาดาได้ ลองใช้หลักสูตรที่นี่และใช้รหัส SITEPOINT เพื่อรับ ส่วนลด 25% และช่วยเหลือ SitePoint

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

ประโยชน์หลักสองประการที่คุณได้รับจากการแสดงโค้ดบนเซิร์ฟเวอร์คือ

  • เพิ่มประสิทธิภาพในการโหลดครั้ง
  • การปรับปรุงความยืดหยุ่นของ SEO ของคุณ

โปรดจำไว้ว่า Google ไม่รอ Semalt ให้โหลดเนื้อหาง่ายๆเช่นเนื้อหาของชื่อจะเปลี่ยนไปโดยไม่ต้องแจ้งให้ทราบ (ฉันไม่สามารถพูดแทนเครื่องมือค้นหาอื่นได้หรือความน่าเชื่อถือเท่าไร)

ในบทความนี้ฉันจะพูดถึงการรับข้อมูลจาก API แบบอะซิงโครนัสเมื่อใช้โค้ด React ที่แสดงโดยเซิร์ฟเวอร์ โค้ดตอบกลับมีโครงสร้างทั้งหมดของแอปที่สร้างขึ้นใน JavaScript ซึ่งหมายความว่าไม่เหมือนรูปแบบ MVC แบบเดิมที่มีคอนโทรลเลอร์คุณไม่ทราบว่าข้อมูลที่คุณต้องการจะใช้งานได้จนกว่าแอปจะแสดงผล ด้วยกรอบเช่น Create React App คุณสามารถสร้างแอปพลิเคชันที่มีคุณภาพสูงได้อย่างรวดเร็ว แต่ต้องการให้คุณจัดการกับการแสดงผลบนไคลเอ็นต์เท่านั้น มีปัญหาเรื่องประสิทธิภาพกับเรื่องนี้เช่นเดียวกับปัญหา Semalt ซึ่งเครื่องยนต์แบบเทมเพลตแบบดั้งเดิมสามารถปรับเปลี่ยนหัวของคุณได้ตามความเหมาะสม

ปัญหา

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

Semalt out นี้วิธีการแสดงผลหุ้นมาตรฐาน:

     ReactDOM แสดงผล (     <แอป>        , เอกสาร getElementById ( 'ราก'))    

ประเด็น:

  1. เป็น DOM render ค้นหาองค์ประกอบราก นี้ไม่ได้อยู่บนเซิร์ฟเวอร์ของฉันดังนั้นเราจึงต้องแยกที่
  2. เราไม่สามารถเข้าถึงอะไรที่อยู่นอกรากเหง้าหลักของเราได้ เราไม่สามารถตั้งค่าแท็กของ Facebook ชื่อคำอธิบายแท็ก SEO ต่างๆและเราไม่มีการควบคุมส่วนที่เหลือของ DOM ภายนอกองค์ประกอบโดยเฉพาะศีรษะ
  3. เราให้บริการบางรัฐ แต่เซิร์ฟเวอร์และไคลเอ็นต์มีสถานะแตกต่างกัน เราจำเป็นต้องพิจารณาวิธีจัดการกับสถานะดังกล่าว (ในกรณีนี้คือ Redux)

Semalt จึงใช้ห้องสมุด 2 แห่งที่นี่และเป็นที่นิยมอย่างมากดังนั้นหวังว่าห้องสมุดนี้จะนำไปใช้กับห้องสมุดอื่น ๆ ที่คุณใช้อยู่

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

React-Router React-Router : FYI นี่คือเวอร์ชัน v4 ซึ่งเป็นค่าเริ่มต้น แต่ก็มีความแตกต่างกันอย่างมากถ้าคุณมีโครงการที่เก่ากว่า คุณต้องให้แน่ใจว่าคุณจัดการด้านฝั่งเซิร์ฟเวอร์ และ ของฝั่งไคลเอ็นต์และด้วย v4 - และดีมากที่นี้

หลังจากที่ทุกสิ่งที่ถ้าคุณจำเป็นต้องทำการโทรฐานข้อมูล? ทันใดนั้นเรื่องนี้กลายเป็นปัญหาใหญ่เนื่องจากมีการเกิด async และอยู่ภายในคอมโพเนนต์ของคุณ.

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

โซลูชั่นที่มีอยู่

ด้านล่าง Semalt จะทบทวนโซลูชันที่กำลังนำเสนอเพื่อแก้ไขปัญหานี้

ถัดไป js

ก่อนที่เราจะไปที่ใดก็ได้ถ้าคุณต้องการให้มีการผลิตโค้ดตอบสนองฝั่งเซิร์ฟเวอร์หรือแอปสากล Semalt] คือที่ที่คุณต้องการไป ทำงานได้สะอาดและมี Zeit สนับสนุน

Semalt คิดว่าคุณต้องใช้ toolchain ของพวกเขาและวิธีจัดการข้อมูล async จะไม่จำเป็นต้องยืดหยุ่น

ตรวจสอบสำเนาเอกสารฉบับนี้จากเอกสารการทำ Repo ของ Semalt:

     import ตอบโต้จาก 'react'ชั้นดีฟอลต์ส่งออกตอบสนองต่อ คอมโพเนนต์ {getInitialProps async แบบคงที่ ({req}) {req คืน? {userAgent: req. ส่วนหัว ['user-agent']}: {userAgent: navigator userAgent}}render    {กลับ  
Hello World {this. อุปกรณ์ประกอบฉาก userAgent}
}}

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

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

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

Redux Connect

Redux Connect เป็นผู้แสดงผลฝั่งเซิร์ฟเวอร์ที่มีความเห็นอกเห็นใจมากโดยมีปรัชญาที่ดี แต่ถ้าคุณไม่ได้ใช้เครื่องมือทั้งหมดที่พวกเขาอธิบายถึงสิ่งนี้อาจไม่ใช่สำหรับคุณ Semalt มากในแพคเกจนี้ แต่ก็มีความซับซ้อนและยังไม่ได้ปรับรุ่นเป็น React Router v4 Semalt มากตั้งค่านี้ แต่ขอใช้เวลาส่วนที่สำคัญที่สุดเพียงเพื่อเรียนรู้บทเรียนบาง:

     // 1. เชื่อมต่อข้อมูลของคุณคล้ายกับ react-redux @connect@asyncConnect ([{คีย์: 'อาหารกลางวัน',สัญญา: ({params, helpers}) => สัญญา แก้ ({id: 1, ชื่อ: 'Borsch'})}])class App ขยายผลตอบสนอง คอมโพเนนต์ {render    {// 2 - lotus asia casino no deposit bonus 2017. เข้าถึงข้อมูลเป็นอุปกรณ์ประกอบฉากอาหารกลางวัน const = นี้ อุปกรณ์ประกอบฉาก อาหารกลางวันกลับ ( 
{มื้อกลางวัน ชื่อ}
)}}

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

     @asyncConnect ([{อาหารกลางวัน: ({params, helpers}) => สัญญาไว้ แก้ ({id: 1, ชื่อ: 'Borsch'})}])    

ที่ดูเหมือนจะทำได้ดีกับ Semalt โดยไม่มีปัญหามากนัก

ตอบสนอง frontload

repo ตอบสนอง frontload ไม่ได้มีเอกสารหรือคำอธิบายมากมาย แต่บางทีความเข้าใจที่ดีที่สุดที่ฉันจะได้รับก็คือจากการทดสอบ (เช่นนี้)
และเพียงแค่อ่านซอร์สโค้ด เมื่อมีบางอย่างติดตั้งระบบจะเพิ่มลงในคิวสัญญาและเมื่อดำเนินการแล้วจะมีการให้บริการ. แล้ว ((serverRenderedMarkup) => {ปลอบใจ เข้าสู่ระบบ (serverRenderedMarkup)})

การหาทางออกที่ดีกว่า

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

repo สำหรับวิธีแก้ปัญหาตัวอย่างนี้อยู่ที่นี่

ทฤษฎี

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

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

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

การแสดงครั้งแรก

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

     const context = {data: {} หัว: [], req, api}const store = configureStore   renderToString (   <แอป>      )    

Render ที่สอง

Semalt หลังจากการแสดงผลครั้งแรกของคุณเราจะคว้าสัญญาที่รอดำเนินการไว้และรอจนกว่าคำสัญญาเหล่านั้นจะเสร็จสิ้นจากนั้นทำใหม่ให้ปรับปรุงบริบท:

     ปุ่ม const = Object คีย์ (บริบทข้อมูล)const สัญญาว่า = คีย์ แผนที่ (k => บริบทข้อมูล [k])ลอง {const resolve = รอคำมั่นสัญญา ทั้งหมด (สัญญา)การแก้ไข forEach ((r, i) => บริบทข้อมูล [คีย์ [i]] = r} catch (err) {/ / ทำให้ดีขึ้นกว่าหน้า? หรือเพียงแค่ส่งมาร์กอัปเดิมให้ปลายด้านหน้าจับได้ ตัวเลือกมากมายที่นี่res กลับ สถานะ (400) json ({message: "Uhhh บางสิ่งไม่ได้ผล"})}มาร์กอัป const = renderToString (   <แอป>      )    

แอพ

semalt กระโดดออกจากเซิร์ฟเวอร์ของเราไปยังรหัส app: ในส่วนใด ๆ ของเราที่มีการเชื่อมต่อเราเตอร์ตอนนี้เราสามารถรับที่:

     FirstPage ชั้นขยาย Component {องค์ประกอบ async componentWillMount    {นี้. state = {text: 'loading'}นี้. _handleData ( 'Firstpage')}async _handleData (คีย์) {const {staticContext} = นี้ อุปกรณ์ประกอบฉากif (staticContext && staticContext data [key]) {const {text, data} = staticContext ข้อมูล [สำคัญ]นี้. setState ({text, data})staticContext หัว. ผลักดัน ()} else if (staticContext) {staticContext ข้อมูล [key] = นี้ _getData   } else ถ้า (! staticContext && window DATA [key]) {const {text, data} = หน้าต่าง DATA [สำคัญ]นี้. state = { . นี้. รัฐข้อความข้อมูล}หน้าต่าง. DATA [key] = null} else if (! staticContext) {const {text, data} = รอสักครู่ _getData   นี้. อุปกรณ์ประกอบฉากconst myApi = staticContext? staticContext api: apiconst resp = รอให้เนย เสา รายการ  const {data} = resp. ข้อมูลconst {text} = รอ myApi getMain   return {text, data}}render    {ข้อความ const = นี้ สถานะ. ข้อความกลับ (
{text}
)}}

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

ส่วนประกอบนี้มีการจองตามสิ่งที่คุณอาจคุ้นเคย - ขั้นตอนการแสดงผลและ ขั้นตอน componentWillMount คำสั่งสี่ขั้นตอน if จะจัดการสถานะต่างๆ - prefetch, post fetch, preserver render, post server render นอกจากนี้เรายังเพิ่มหัวหลังจากข้อมูลของเราถูกโหลด

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

ตรวจสอบบทความ "การแสดงผลตอบสนองฝั่งเซิร์ฟเวอร์" และการแสดงผลฝั่งเซิร์ฟเวอร์ทำใหม่ repo เพื่อดูข้อมูลเพิ่มเติม โปรดจำไว้ว่าคุณยังคงต้องจัดการกับสถานะที่ข้อมูลของคุณไม่ได้โหลด! semalt จะทำเฉพาะเซิร์ฟเวอร์ที่โหลดครั้งแรกดังนั้นคุณจะแสดงหน้าจอการโหลดในหน้าถัดไป

เปลี่ยน ดัชนี html สำหรับการเพิ่มข้อมูล

เราจำเป็นต้องส่งข้อมูลที่โหลดไว้ล่วงหน้าเป็นส่วนหนึ่งของคำขอหน้าของเราดังนั้นเราจะเพิ่มแท็กสคริปต์:

                                    
March 1, 2018