จะหลีกเลี่ยงการห่อ <div> พิเศษใน React ได้อย่างไร?


115

วันนี้ฉันได้เริ่มเรียนรู้ ReactJS และหลังจากผ่านไปหนึ่งชั่วโมงต้องเผชิญกับปัญหา .. ฉันต้องการแทรกส่วนประกอบที่มีสองแถวภายใน div บนหน้าตัวอย่างง่ายๆของสิ่งที่ฉันกำลังทำอยู่ด้านล่าง

ฉันมี html:

<html>
..
  <div id="component-placeholder"></div>
..
</html>

ฟังก์ชัน Render ดังนี้:

...
render: function() {

    return(
        <div className="DeadSimpleComponent">
            <div className="DeadSimpleComponent__time">10:23:12</div >
            <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
        </div>
    )
}
....

และด้านล่างฉันเรียกว่า render:

ReactDOM.render(<DeadSimpleComponent/>, document.getElementById('component-placeholder'));

HTML ที่สร้างขึ้นมีลักษณะดังนี้:

<html>
..
  <div id="component-placeholder">
    <div class="DeadSimpleComponent">
            <div class="DeadSimpleComponent__time">10:23:12</div>
            <div class="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
    </div>
</div>
..
</html>

ปัญหาที่ฉันไม่พอใจมากที่ React บังคับให้ฉันรวมทั้งหมดใน div "DeadSimpleComponent" อะไรคือวิธีแก้ปัญหาที่ง่ายและดีที่สุดโดยไม่มีการปรับแต่ง DOM อย่างชัดเจน

อัปเดต 28/7/2017: ผู้ดูแล React เพิ่มความเป็นไปได้นั้นใน React 16 Beta 1

ตั้งแต่React 16.2คุณสามารถทำได้:

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}

4
การตั้งชื่อที่สมบูรณ์แบบ ;-)
Kirill Reznikov

ฉันขอดูไฟล์ HTML ของคุณได้ไหม ฉันอ่านคำถามของคุณผิด ฉันอาจมีวิธีแก้ปัญหาได้
Louis93


คุณมีปัญหากับส่วนประกอบที่มีองค์ประกอบเดียวหรือไม่? จริงๆ?
Dominic

คุณหมายถึงอะไร? ฉันแค่ลอง React ไม่น่าจะซับซ้อนมาก .. แต่ข้อ จำกัด ดูน่ารำคาญ
Kirill Reznikov

คำตอบ:


144

ข้อกำหนดนี้ถูกลบออกใน React version (16.0)] 1ดังนั้นตอนนี้คุณสามารถหลีกเลี่ยง Wrapper นั้นได้

คุณสามารถใช้ React.Fragment เพื่อแสดงรายการองค์ประกอบโดยไม่ต้องสร้างโหนดแม่ตัวอย่างอย่างเป็นทางการ:

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

เพิ่มเติมที่นี่: Fragments


1
ข่าวดี DmitryUlyanets มีวันที่วางจำหน่ายตามแผนหรือไม่?
Jonas Carlbaum

เผยแพร่ตั้งแต่วันที่ 26 กันยายน 2017 ดูreactjs.org/blog/2017/09/26/react-v16.0.html
Tom

57

อัปเดต 2017-12-05: React v16.2.0รองรับการเรนเดอร์แฟรกเมนต์อย่างสมบูรณ์พร้อมการสนับสนุนที่ดีขึ้นสำหรับการส่งคืนลูกหลายตัวจากวิธีการเรนเดอร์คอมโพเนนต์โดยไม่ต้องระบุคีย์ในชายด์:

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}

หากคุณใช้ React เวอร์ชันก่อน v16.2.0 คุณสามารถใช้<React.Fragment>...</React.Fragment>แทนได้:

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

ต้นฉบับ:

React v16.0 แนะนำการส่งคืนอาร์เรย์ขององค์ประกอบในวิธีการเรนเดอร์โดยไม่ต้องรวมไว้ใน div: https://reactjs.org/blog/2017/09/26/react-v16.0.html

render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}

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

ในอนาคตเราน่าจะเพิ่มไวยากรณ์แฟรกเมนต์พิเศษให้กับ JSX ที่ไม่ต้องใช้คีย์


ไวยากรณ์ชวเลขใหม่ของ <> </> ดีมาก ฉันยังคงมีความรู้สึกหลากหลายเกี่ยวกับเรื่องนี้
Thulani Chivandikwa

@ThulaniChivandikwa คุณคิดที่จะแสดงความวิตกกังวลเกี่ยวกับไวยากรณ์ชวเลขได้หรือไม่?
ทอม

1
ฉันคิดว่ามันเกี่ยวกับแนวคิดของแท็กว่างที่แปลกใน JSX และไม่ค่อยเข้าใจง่ายนักเว้นแต่คุณจะรู้ว่ามันทำอะไร
Thulani Chivandikwa

7

คุณสามารถใช้ได้:

render(){
    return (
        <React.Fragment>
           <div>Some data</div>
           <div>Som other data</div>
        </React.Fragment>
    )
}

สำหรับรายละเอียดเพิ่มเติมโปรดดูเอกสารนี้


3

ใช้ [] แทน () เพื่อห่อผลตอบแทนทั้งหมด

render: function() {
  return[
    <div className="DeadSimpleComponent__time">10:23:12</div >
    <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
  ]
}


1

นี้ยังคงต้อง , แต่ React ตอนนี้ให้แน่ใจว่าจะสร้างองค์ประกอบโดยไม่ต้องสร้างองค์ประกอบ DOM เพิ่มเติม

ห่อพิเศษที่จำเป็น (ปกติกับผู้ปกครองdiv) เพราะปฏิกิริยาcreateElementวิธีการต้องมีพารามิเตอร์ซึ่งเป็นtype แต่นี้คือก่อนที่พวกเขาแนะนำตอบสนองeither a tag name string (such as 'div' or 'span'), a React component type (a class or a function)Fragment

อ้างถึงเอกสาร api ใหม่นี้สำหรับ createElement

React.createElement : สร้างและส่งคืนองค์ประกอบ React ใหม่ของประเภทที่กำหนด อาร์กิวเมนต์ชนิดสามารถเป็นได้ทั้งสตริงชื่อแท็ก (เช่น 'div' หรือ 'ช่วง') ซึ่งเป็นปฏิกิริยาประเภทส่วนประกอบ (ชั้นเรียนหรือฟังก์ชั่น) หรือตอบสนองประเภทชิ้นส่วน

นี่เป็นตัวอย่างอย่างเป็นทางการอ้างถึงReact.Fragment

render() {
  return (
    <React.Fragment>
      Some text.
      <h2>A heading</h2>
    </React.Fragment>
  );
}

0

คุณจะไม่สามารถกำจัดdivองค์ประกอบนั้นได้ React.render () จำเป็นต้องส่งคืนโหนด DOM ที่ถูกต้องหนึ่งโหนด


div ของถูกละเว้น Knockout.JS ทำสิ่งเดียวกัน การมี div โดยไม่มีการจัดแต่งทรงผมที่ส่วนนอกของส่วนประกอบของคุณจะไม่มีผลอะไรเลย
Chris Hawkes

16
@ChrisHawkes ไม่เห็นด้วย หนึ่ง wrapper div มีผลต่อตัวเลือก css
Downhillski

เมื่อทำงานกับองค์ประกอบเชิงความหมายที่คุณไม่ต้องการเป็นส่วนประกอบของปฏิกิริยาทั้งหมดสิ่งนี้จะกลายเป็นปัญหา สมมติว่ามีแท็กส่วนที่มีองค์ประกอบส่วนหัวและส่วนท้ายและระหว่างนั้นมี google map-container ซึ่งเราไม่ต้องการใช้ใน React ถ้าอย่างนั้นคงจะดีถ้ามี header เป็นส่วนประกอบ React และ Footer เป็นส่วนประกอบ React โดยไม่ต้องรวม div: s พิเศษไว้ข้างนอกภายในส่วนประกอบ React ... นั่นคือการออกแบบที่โง่ ๆ ธรรมดาถ้าคุณสนใจเกี่ยวกับ html คุณเอาท์พุท ...
Jonas Carlbaum

0

นี่คือวิธีหนึ่งในการแสดงผลคอมโพเนนต์ "transculent":

import React from 'react'

const Show = (props) => {
  if (props.if || false) {
    return (<React.Fragment>{props.children}</React.Fragment>)
  }
  return '';
};

----


<Show if={yomama.so.biq}>
    <img src="https://yomama.so.biq">
    <h3>Yoamama</h3>
<Show>

ป้อนคำอธิบายภาพที่นี่


0

มีวิธีแก้ปัญหาด้วย โค้ดบล็อกด้านล่างสร้างแฟรกเมนต์โดยไม่ต้องใช้ React.Fragment

return [1,2,3].map(i=>{
if(i===1) return <div key={i}>First item</div>
if(i===2) return <div key={i}>Second item</div>
return <div key={i}>Third item</div>
})

0

ฉันรู้ว่าคำถามนี้ได้รับคำตอบแล้วแน่นอนว่าคุณสามารถใช้ React.Fragment ซึ่งไม่ได้สร้างโหนด แต่ให้คุณจัดกลุ่มสิ่งต่างๆเช่น div

นอกจากนี้หากคุณต้องการความสนุกสนานคุณสามารถใช้ (และเรียนรู้สิ่งต่างๆมากมาย) โหมด React ที่ลบ div พิเศษออกไปและสำหรับสิ่งนี้ฉันต้องการแบ่งปันวิดีโอที่ยอดเยี่ยมเกี่ยวกับวิธีที่คุณสามารถทำได้บนฐานรหัสการตอบสนองเอง

https://www.youtube.com/watch?v=aS41Y_eyNrU

แน่นอนว่านี่ไม่ใช่สิ่งที่คุณควรทำในทางปฏิบัติ แต่เป็นโอกาสในการเรียนรู้ที่ดี

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