이미 몇 가지 훌륭한 답변이 있지만, 나는 그들이 잘 설명되지 않았다고 생각하며 주어진 방법 중 일부에는 사람들을 여행 할 수있는 문제가 있습니다. 이 작업을 수행하고 장단점을 설명하는 세 가지 주요 방법 (한 가지 주제 이외의 옵션)을 살펴 보겠습니다. 옵션 1을 많이 권장하고 올바르게 사용하지 않으면 해당 옵션에 많은 잠재적 인 문제가 있기 때문에 주로 이것을 쓰고 있습니다.
옵션 1 : 부모의 조건부 렌더링.
구성 요소를 한 번만 렌더링하고 그대로 두지 않는 한이 방법이 마음에 들지 않습니다. 가시성을 토글 할 때마다 구성 요소가 처음부터 새로 작성되도록하는 문제가 발생합니다. 다음은 그 예입니다. 부모 LoginControl에서 LogoutButton 또는 LoginButton이 조건부로 렌더링됩니다. 이것을 실행하면 각 버튼 클릭시 생성자가 호출되는 것을 알 수 있습니다. 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, 렌더링 등의 코드가 비싸면 구성 요소 표시 속도가 크게 느려집니다. 또한 숨겨져있을 때 상태를 유지하고 표시 할 때 복원하려는 상태 저장 구성 요소에는이 기능을 사용할 수 없습니다. 한 가지 장점은 숨겨진 구성 요소를 선택할 때까지 전혀 만들지 않는다는 것입니다. 따라서 숨겨진 구성 요소는 초기 페이지로드를 지연시키지 않습니다. 전환 할 때 상태 저장 구성 요소를 재설정하려는 경우도 있습니다. 어떤 경우에는 이것이 최선의 선택입니다.
옵션 2 : 자식의 조건부 렌더링
이렇게하면 두 구성 요소가 한 번 생성됩니다. 그런 다음 구성 요소가 숨겨져 있으면 나머지 렌더링 코드를 단락시킵니다. visible prop을 사용하여 다른 방법으로 다른 로직을 단락시킬 수도 있습니다. 코드 펜 페이지에서 console.log를 확인하십시오. 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는 첫 페이지로드시 모든 구성 요소의 init를 실행합니다. 첫로드를 느리게합니다. 다시 참고해야합니다. 조건에 따라 구성 요소를 한 번만 표시하고 전환하지 않거나 toggledm 일 때 재설정하려는 경우 옵션 1이 적합하고 아마도 가장 좋은 옵션 일 것입니다.
그러나 느린 페이지로드가 문제인 경우 수명주기 방법에 값 비싼 코드가 있으며 일반적으로 좋은 생각이 아닙니다. 고가의 코드를 라이프 사이클 메소드에서 제거하여 페이지로드 속도가 느려질 수 있습니다. ComponentDidMount에 의해 시작된 비동기 함수로 이동하고 콜백이 setState ()를 사용하여 상태 변수에 넣도록합니다. 상태 변수가 null이고 구성 요소가 표시되면 render 함수가 자리 표시자를 반환하도록합니다. 그렇지 않으면 데이터를 렌더링하십시오. 이렇게하면 페이지가 빠르게로드되고 탭이로드 될 때 채워집니다. 논리를 부모로 이동하고 결과를 자식으로 소품으로 푸시 할 수도 있습니다. 이렇게하면 먼저로드 할 탭의 우선 순위를 지정할 수 있습니다. 또는 결과를 캐시하고 구성 요소가 처음 표시 될 때만 로직을 실행하십시오.
옵션 3 : 수업 숨기기
클래스 숨기기는 아마도 구현하기 가장 쉬운 방법 일 것입니다. 언급했듯이 display : none으로 CSS 클래스를 만들고 prop를 기반으로 클래스를 할당하십시오. 단점은 모든 숨겨진 구성 요소의 전체 코드가 호출되고 모든 숨겨진 구성 요소가 DOM에 첨부됩니다. (옵션 1은 숨겨진 컴포넌트를 전혀 생성하지 않습니다. 그리고 옵션 2는 컴포넌트가 숨겨진 경우 불필요한 코드를 단락시키고 컴포넌트를 DOM에서 완전히 제거합니다.) 다른 답변이지만 말할 수는 없습니다.
옵션 4 : 하나의 구성 요소이지만 소품을 변경하십시오. 또는 구성 요소가 전혀없고 HTML을 캐시 할 수도 있습니다.
이것은 모든 응용 프로그램에서 작동하지는 않으며 구성 요소를 숨기는 것이 아니기 때문에 주제와는 관련이 없지만 일부 사용 사례의 경우 숨기는 것보다 더 나은 솔루션 일 수 있습니다. 탭이 있다고 가정 해 봅시다. 하나의 React Component를 작성하고 props를 사용하여 탭에 표시되는 내용을 변경할 수 있습니다. JSX를 상태 변수에 저장하고 소품을 사용하여 렌더링 함수에서 반환 할 JSX를 결정할 수도 있습니다. JSX를 생성해야하는 경우이를 수행하고이를 상위에 캐시하고 올바른 것을 소품으로 보냅니다. 또는 자식에서 생성하여 자식 상태로 캐시하고 props를 사용하여 활성 상태를 선택하십시오.