มีคำตอบที่ยอดเยี่ยมหลายคำอยู่แล้ว แต่ฉันไม่คิดว่าพวกเขาได้รับการอธิบายที่ดีมากและวิธีการหลายอย่างที่ให้ไว้มี gotchas บางอย่างที่อาจทำให้คนเดินทาง ดังนั้นฉันจะไปสามวิธีหลัก (บวกหนึ่งตัวเลือกนอกหัวข้อ) เพื่อทำสิ่งนี้และอธิบายข้อดีข้อเสีย ฉันมักจะเขียนสิ่งนี้เพราะแนะนำให้ใช้ตัวเลือกที่ 1 มากและมีปัญหาที่อาจเกิดขึ้นกับตัวเลือกนั้นหากไม่ได้ใช้อย่างถูกต้อง
ตัวเลือก 1: การแสดงผลตามเงื่อนไขในพาเรนต์
ฉันไม่ชอบวิธีนี้เว้นแต่คุณจะแสดงองค์ประกอบเพียงครั้งเดียวแล้วปล่อยไว้ที่นั่น ปัญหาคือมันจะทำให้เกิดปฏิกิริยาตอบสนองในการสร้างองค์ประกอบตั้งแต่เริ่มต้นทุกครั้งที่คุณสลับการมองเห็น นี่คือตัวอย่าง LogoutButton หรือ LoginButton แสดงผลแบบมีเงื่อนไขใน LoginControl หลัก หากคุณเรียกใช้สิ่งนี้คุณจะสังเกตเห็นว่าตัวสร้างกำลังถูกเรียกใช้ในการคลิกแต่ละปุ่ม https://codepen.io/Kelnor/pen/LzPdpN?editors=1111
class LoginControl extends React.Component {
constructor(props) {
super(props);
this.handleLoginClick = this.handleLoginClick.bind(this);
this.handleLogoutClick = this.handleLogoutClick.bind(this);
this.state = {isLoggedIn: false};
}
handleLoginClick() {
this.setState({isLoggedIn: true});
}
handleLogoutClick() {
this.setState({isLoggedIn: false});
}
render() {
const isLoggedIn = this.state.isLoggedIn;
let button = null;
if (isLoggedIn) {
button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
button = <LoginButton onClick={this.handleLoginClick} />;
}
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
);
}
}
class LogoutButton extends React.Component{
constructor(props, context){
super(props, context)
console.log('created logout button');
}
render(){
return (
<button onClick={this.props.onClick}>
Logout
</button>
);
}
}
class LoginButton extends React.Component{
constructor(props, context){
super(props, context)
console.log('created login button');
}
render(){
return (
<button onClick={this.props.onClick}>
Login
</button>
);
}
}
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
ReactDOM.render(
<LoginControl />,
document.getElementById('root')
);
ตอนนี้ React ค่อนข้างเร็วในการสร้างส่วนประกอบตั้งแต่เริ่มต้น อย่างไรก็ตามมันยังคงมีการเรียกรหัสของคุณเมื่อสร้างมัน ดังนั้นถ้าคอนสตรัคเตอร์ componentDidMount, render, ฯลฯ โค้ดของคุณมีราคาแพงมันจะช้าลงอย่างมากในการแสดงส่วนประกอบ นอกจากนี้ยังหมายความว่าคุณไม่สามารถใช้สิ่งนี้กับส่วนประกอบที่เป็นสถานะที่คุณต้องการให้สถานะถูกเก็บรักษาไว้เมื่อถูกซ่อน (และเรียกคืนเมื่อแสดง) ข้อดีอย่างหนึ่งคือส่วนประกอบที่ซ่อนไม่ได้ถูกสร้างขึ้นจนกว่าจะถูกเลือก ดังนั้นส่วนประกอบที่ซ่อนไว้จะไม่ทำให้การโหลดหน้าเริ่มต้นของคุณล่าช้า อาจมีบางกรณีที่คุณต้องการให้องค์ประกอบที่เป็นสถานะที่จะรีเซ็ตเมื่อสลับ ในกรณีนี้นี่คือตัวเลือกที่ดีที่สุดของคุณ
ตัวเลือกที่ 2: การแสดงผลแบบมีเงื่อนไขในเด็ก
สิ่งนี้จะสร้างองค์ประกอบทั้งสองครั้ง จากนั้นทำให้วงจรการแสดงผลส่วนที่เหลือสั้นลงหากส่วนประกอบถูกซ่อน นอกจากนี้คุณยังสามารถลัดวงจรตรรกะอื่น ๆ ในวิธีอื่น ๆ โดยใช้เสาที่มองเห็นได้ สังเกตเห็น console.log ในหน้า codepen https://codepen.io/Kelnor/pen/YrKaWZ?editors=0011
class LoginControl extends React.Component {
constructor(props) {
super(props);
this.handleLoginClick = this.handleLoginClick.bind(this);
this.handleLogoutClick = this.handleLogoutClick.bind(this);
this.state = {isLoggedIn: false};
}
handleLoginClick() {
this.setState({isLoggedIn: true});
}
handleLogoutClick() {
this.setState({isLoggedIn: false});
}
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
<LoginButton isLoggedIn={isLoggedIn} onClick={this.handleLoginClick}/>
<LogoutButton isLoggedIn={isLoggedIn} onClick={this.handleLogoutClick}/>
</div>
);
}
}
class LogoutButton extends React.Component{
constructor(props, context){
super(props, context)
console.log('created logout button');
}
render(){
if(!this.props.isLoggedIn){
return null;
}
return (
<button onClick={this.props.onClick}>
Logout
</button>
);
}
}
class LoginButton extends React.Component{
constructor(props, context){
super(props, context)
console.log('created login button');
}
render(){
if(this.props.isLoggedIn){
return null;
}
return (
<button onClick={this.props.onClick}>
Login
</button>
);
}
}
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
ReactDOM.render(
<LoginControl />,
document.getElementById('root')
);
ทีนี้ถ้าตรรกะการเริ่มต้นรวดเร็วและลูกนั้นไร้สัญชาติคุณจะไม่เห็นความแตกต่างด้านประสิทธิภาพหรือฟังก์ชั่น อย่างไรก็ตามทำไมให้ React สร้างส่วนประกอบใหม่ทุกครั้งที่เปิดใช้งาน หากการเตรียมใช้งานมีราคาแพงอย่างไรก็ตามตัวเลือก 1 จะเรียกใช้ทุกครั้งที่คุณสลับส่วนประกอบซึ่งจะทำให้หน้าช้าลงเมื่อสลับ ตัวเลือกที่ 2 จะเรียกใช้ส่วนประกอบทั้งหมดในการโหลดหน้าแรก ชะลอการโหลดครั้งแรก ควรทราบอีกครั้ง หากคุณเพิ่งแสดงองค์ประกอบเพียงครั้งเดียวตามเงื่อนไขและไม่เปิดใช้งานหรือคุณต้องการรีเซ็ตเมื่อเปิดใช้งานตัวเลือกที่ 1 นั้นใช้ได้และอาจเป็นตัวเลือกที่ดีที่สุด
หากการโหลดหน้าเว็บช้าเป็นปัญหาแสดงว่าคุณมีรหัสราคาแพงในวิธีการใช้รอบการทำงานและโดยทั่วไปก็ไม่ใช่ความคิดที่ดี คุณสามารถและควรแก้ปัญหาการโหลดหน้าเว็บช้าโดยการย้ายรหัสราคาแพงออกจากวิธีวงจรชีวิต ย้ายไปยังฟังก์ชัน async ที่ kicked off โดย ComponentDidMount และให้การเรียกกลับวางไว้ในตัวแปรสถานะด้วย setState () หากตัวแปรสถานะเป็นโมฆะและส่วนประกอบนั้นสามารถมองเห็นได้แล้วให้ฟังก์ชั่นการแสดงผลคืนตัวยึด มิฉะนั้นแสดงข้อมูล วิธีนี้หน้าจะโหลดอย่างรวดเร็วและเติมแท็บขณะที่โหลด นอกจากนี้คุณยังสามารถย้ายตรรกะไปที่ผู้ปกครองและผลักดันผลลัพธ์ไปยังเด็ก ๆ เป็นอุปกรณ์ประกอบฉาก วิธีนี้คุณสามารถจัดลำดับความสำคัญของแท็บที่โหลดก่อน หรือแคชผลลัพธ์และรันเฉพาะตรรกะในครั้งแรกที่ส่วนประกอบถูกแสดง
ตัวเลือก 3: การซ่อนคลาส
การซ่อนคลาสน่าจะเป็นวิธีที่ง่ายที่สุด ดังที่ได้กล่าวไว้คุณเพียงแค่สร้างคลาส CSS พร้อมจอแสดงผล: ไม่มีและกำหนดคลาสตามเสา ข้อเสียคือรหัสทั้งหมดของทุกองค์ประกอบที่ซ่อนอยู่เรียกว่าและส่วนประกอบที่ซ่อนอยู่ทั้งหมดจะแนบกับ DOM (ตัวเลือกที่ 1 ไม่ได้สร้างส่วนประกอบที่ซ่อนอยู่เลยและตัวเลือกที่ 2 ไม่จำเป็นต้องใช้รหัสลัดเมื่อส่วนประกอบถูกซ่อนและเอาส่วนประกอบออกจาก DOM ทั้งหมด) ดูเหมือนว่านี่จะเร็วกว่าในการสลับการมองเห็นตามการทดสอบบางอย่าง คำตอบอื่น ๆ แต่ฉันไม่สามารถพูดได้
ตัวเลือก 4: องค์ประกอบเดียว แต่เปลี่ยนอุปกรณ์ประกอบฉาก หรืออาจจะไม่มีส่วนประกอบเลยและแคช HTML
อันนี้จะไม่ทำงานสำหรับทุกแอปพลิเคชันและเป็นหัวข้อที่ปิดเพราะมันไม่ได้เกี่ยวกับการซ่อนส่วนประกอบ แต่มันอาจเป็นทางออกที่ดีกว่าสำหรับการใช้งานบางกรณีมากกว่าการซ่อน สมมติว่าคุณมีแท็บ อาจเป็นไปได้ที่จะเขียนหนึ่งองค์ประกอบการเกิดปฏิกิริยาและเพียงแค่ใช้อุปกรณ์ประกอบฉากเพื่อเปลี่ยนสิ่งที่ปรากฏในแท็บ คุณสามารถบันทึก JSX เพื่อระบุตัวแปรและใช้ prop เพื่อตัดสินใจว่า JSX ใดที่จะกลับมาในฟังก์ชั่นการแสดงผล หากต้องสร้าง JSX ให้ทำและแคชในพาเรนต์และส่งอันที่ถูกต้องเป็นเสา หรือสร้างในเด็กและแคชไว้ในสถานะของเด็กและใช้อุปกรณ์ประกอบฉากเพื่อเลือกหนึ่งที่ใช้งานอยู่