Facebook React의 JSX로 조건부 요소를 사용하고 DRY를 유지하는 방법은 무엇입니까?
JSX에 요소를 선택적으로 포함시키는 방법은 무엇입니까? 다음은 컴포넌트가 전달 된 경우 컴포넌트에 있어야하는 배너를 사용하는 예제입니다. 피하고 싶은 것은 if 문에서 HTML 태그를 복제해야합니다.
render: function () {
var banner;
if (this.state.banner) {
banner = <div id="banner">{this.state.banner}</div>;
} else {
banner = ?????
}
return (
<div id="page">
{banner}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
배너를 정의되지 않은 상태로두면 포함되지 않습니다.
이건 어때? 간단한 도움 If
컴포넌트를 정의 해 봅시다 .
var If = React.createClass({
render: function() {
if (this.props.test) {
return this.props.children;
}
else {
return false;
}
}
});
그리고 이런 식으로 사용하십시오 :
render: function () {
return (
<div id="page">
<If test={this.state.banner}>
<div id="banner">{this.state.banner}</div>
</If>
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
업데이트 : 내 대답이 대중화 되면서이 솔루션과 관련된 가장 큰 위험에 대해 경고해야한다고 생각합니다. 다른 답변에서 지적했듯이 <If />
구성 요소 내부의 코드 는 조건이 true인지 false인지에 관계없이 항상 실행됩니다. 따라서 다음 예제 는 banner
is 인 경우 실패 null
합니다 (두 번째 줄의 속성 액세스 참고).
<If test={this.state.banner}>
<div id="banner">{this.state.banner.url}</div>
</If>
사용할 때는주의해야합니다. 대안 (safer) 접근법에 대한 다른 답변을 읽는 것이 좋습니다.
업데이트 2 : 되돌아 보면,이 접근 방식은 위험 할뿐만 아니라 필사적으로 번거 롭습니다. 개발자 (me)가 패턴을 전달하려고 할 때 한 영역에서 다른 영역으로 접근하려고 시도하지만 실제로 작동하지 않습니다 (이 경우 다른 템플릿 언어)의 전형적인 예입니다.
조건부 요소가 필요한 경우 다음과 같이하십시오.
render: function () {
return (
<div id="page">
{this.state.banner &&
<div id="banner">{this.state.banner}</div>}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
else 브랜치가 필요한 경우 삼항 연산자를 사용하십시오.
{this.state.banner ?
<div id="banner">{this.state.banner}</div> :
<div>There is no banner!</div>
}
더 짧고 우아하며 안전합니다. 나는 항상 그것을 사용합니다. 유일한 단점은 else if
쉽게 분기 할 수는 없지만 일반적으로 그렇게하지는 않는다는 것입니다.
어쨌든 이것은 JavaScript의 논리 연산자 가 작동 하는 방식 덕분에 가능 합니다. 논리 연산자는 다음과 같은 작은 트릭을 허용합니다.
<h3>{this.state.banner.title || 'Default banner title'}</h3>
개인적으로 저는 ( JSX In Depth )에 표시되는 삼항식 이 ReactJs 표준을 따르는 가장 자연스러운 방법이라고 생각합니다.
다음 예를 참조하십시오. 첫눈에 약간 지저분하지만 잘 작동합니다.
<div id="page">
{this.state.banner ? (
<div id="banner">
<div class="another-div">
{this.state.banner}
</div>
</div>
) :
null}
<div id="other-content">
blah blah blah...
</div>
</div>
당신은 또한 그것을 쓸 수 있습니다
{ this.state.banner && <div>{...}</div> }
당신이 경우 state.banner
이다 null
하거나 undefined
, 조건의 오른쪽 건너 뜁니다.
If
코드 블록이 있기 때문에 스타일의 구성 요소는 위험 항상 실행 에 관계없이 상태. 예를 들어 다음과 같은 경우 null 예외 banner
가 발생합니다 null
.
//dangerous
render: function () {
return (
<div id="page">
<If test={this.state.banner}>
<img src={this.state.banner.src} />
</If>
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
또 다른 옵션은 인라인 함수를 사용하는 것입니다 (특히 else 문에 유용).
render: function () {
return (
<div id="page">
{function(){
if (this.state.banner) {
return <div id="banner">{this.state.banner}</div>
}
}.call(this)}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
반응 문제의 또 다른 옵션 :
render: function () {
return (
<div id="page">
{ this.state.banner &&
<div id="banner">{this.state.banner}</div>
}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
&& + 코드 스타일 + 작은 구성 요소
이 간단한 테스트 구문 + 코드 스타일 규칙 + 작은 집중 구성 요소는 나에게 가장 읽기 쉬운 옵션입니다. false
, 0
또는 과 같은 허위 값에 특별한주의를 기울여야합니다 ""
.
render: function() {
var person= ...;
var counter= ...;
return (
<div className="component">
{person && (
<Person person={person}/>
)}
{(typeof counter !== 'undefined') && (
<Counter value={counter}/>
)}
</div>
);
}
표기법
ES7 stage-0 do 표기법 구문도 매우 훌륭하며 IDE가 올바르게 지원할 때 확실히 사용합니다.
const Users = ({users}) => (
<div>
{users.map(user =>
<User key={user.id} user={user}/>
)}
</div>
)
const UserList = ({users}) => do {
if (!users) <div>Loading</div>
else if (!users.length) <div>Empty</div>
else <Users users={users}/>
}
자세한 내용은 여기에 있습니다 : ReactJs- "If"컴포넌트 생성 중 ... 좋은 생각입니까?
간단하고 함수를 만듭니다.
renderBanner: function() {
if (!this.state.banner) return;
return (
<div id="banner">{this.state.banner}</div>
);
},
render: function () {
return (
<div id="page">
{this.renderBanner()}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
이것은 내가 개인적으로 항상 따르는 패턴입니다. 코드를 정말 깨끗하고 이해하기 쉽게 만듭니다. Banner
또한 너무 커지면 (또는 다른 장소에서 재사용 할 경우) 자체 구성 요소 로 리팩토링 할 수 있습니다 .
실험적인 ES7 do
구문은 이것을 쉽게 만듭니다. Babel을 사용하는 경우 es7.doExpressions
기능을 활성화 한 후 다음을 수행하십시오.
render() {
return (
<div id="banner">
{do {
if (this.state.banner) {
this.state.banner;
} else {
"Something else";
}
}}
</div>
);
}
http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions를 참조 하십시오
답변에서 이미 언급했듯이 JSX는 두 가지 옵션을 제공합니다.
삼항 연산자
{ this.state.price ? <div>{this.state.price}</div> : null }
논리적 연결
{ this.state.price && <div>{this.state.price}</div> }
그러나 그것들은 작동하지 않습니다 price == 0
.
JSX는 첫 번째 경우에 잘못된 분기를 렌더링하며 논리적으로 연결되는 경우 아무것도 렌더링되지 않습니다. 속성이 0 일 경우 JSX 외부의 if 문만 사용하십시오.
이 구성 요소는 "if"분기에 둘 이상의 요소가있는 경우 작동합니다.
var Display = React.createClass({
render: function() {
if (!this.props.when) {
return false;
}
return React.DOM.div(null, this.props.children);
}
});
용법:
render: function() {
return (
<div>
<Display when={this.state.loading}>
Loading something...
<div>Elem1</div>
<div>Elem2</div>
</Display>
<Display when={!this.state.loading}>
Loaded
<div>Elem3</div>
<div>Elem4</div>
</Display>
</div>
);
},
누군가는이 구성 요소가 코드 읽기에 좋지 않다고 생각합니다. 하지만 내 마음에 자바 스크립트가있는 html은 더 나쁘다.
대부분의 예제에는 조건부로 렌더링되는 "html"한 줄이 있습니다. 조건부로 렌더링 해야하는 여러 줄이있을 때 이것은 읽을 수있는 것처럼 보입니다.
render: function() {
// This will be renered only if showContent prop is true
var content =
<div>
<p>something here</p>
<p>more here</p>
<p>and more here</p>
</div>;
return (
<div>
<h1>Some title</h1>
{this.props.showContent ? content : null}
</div>
);
}
첫 번째 예는 null
조건부와 같은 다른 컨텐츠를 조건부로 렌더링 할 수 있기 때문에 좋습니다.{this.props.showContent ? content : otherContent}
그러나 컨텐츠를 표시하거나 숨기려면 부울, 널 및 정의되지 않음이 무시 되므로 훨씬 좋습니다.
render: function() {
return (
<div>
<h1>Some title</h1>
// This will be renered only if showContent prop is true
{this.props.showContent &&
<div>
<p>something here</p>
<p>more here</p>
<p>and more here</p>
</div>
}
</div>
);
}
React의 구성 요소 인 경우 다른 해결책이 있습니다 .
var Node = require('react-if-comp');
...
render: function() {
return (
<div id="page">
<Node if={this.state.banner}
then={<div id="banner">{this.state.banner}</div>} />
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
보다 명시적인 바로 가기를 사용합니다. IIFE (즉시 호출 된 함수 식) :
{(() => {
if (isEmpty(routine.queries)) {
return <Grid devices={devices} routine={routine} configure={() => this.setState({configured: true})}/>
} else if (this.state.configured) {
return <DeviceList devices={devices} routine={routine} configure={() => this.setState({configured: false})}/>
} else {
return <Grid devices={devices} routine={routine} configure={() => this.setState({configured: true})}/>
}
})()}
내가 만든 https://www.npmjs.com/package/jsx-control-statements를 기본적으로 사용자가 정의 할 수 있습니다, 좀 더 쉽게 그것을 만들 <If>
태그로 조건문을하고 있으므로 내부 코드 것을 원 IFS로 컴파일 <If>
만 가져 조건이 참이면 실행됩니다.
정말 깨끗한 한 줄 버전도 있습니다 ... {this.props.product.title || "제목 없음" }
즉 :
render: function() {
return (
<div className="title">
{ this.props.product.title || "No Title" }
</div>
);
}
술어가 통과하는 경우에만 요소를 안전하게 렌더링하기 위해 https://github.com/ajwhite/render-if 최근에 만들었습니다 .
{renderIf(1 + 1 === 2)(
<span>Hello!</span>
)}
또는
const ifUniverseIsWorking = renderIf(1 + 1 === 2);
//...
{ifUniverseIsWorking(
<span>Hello!</span>
)}
다음과 같이 삼항 연산자를 사용하여 조건부로 요소를 포함 할 수 있습니다.
render: function(){
return <div id="page">
//conditional statement
{this.state.banner ? <div id="banner">{this.state.banner}</div> : null}
<div id="other-content">
blah blah blah...
</div>
</div>
}
함수를 사용하여 구성 요소를 반환하고 렌더링 함수를 얇게 유지할 수 있습니다
class App extends React.Component {
constructor (props) {
super(props);
this._renderAppBar = this._renderAppBar.bind(this);
}
render () {
return <div>
{_renderAppBar()}
<div>Content</div>
</div>
}
_renderAppBar () {
if (this.state.renderAppBar) {
return <AppBar />
}
}
}
다음은 ES6을 사용하는 접근법입니다.
import React, { Component } from 'react';
// you should use ReactDOM.render instad of React.renderComponent
import ReactDOM from 'react-dom';
class ToggleBox extends Component {
constructor(props) {
super(props);
this.state = {
// toggle box is closed initially
opened: false,
};
// http://egorsmirnov.me/2015/08/16/react-and-es6-part3.html
this.toggleBox = this.toggleBox.bind(this);
}
toggleBox() {
// check if box is currently opened
const { opened } = this.state;
this.setState({
// toggle value of `opened`
opened: !opened,
});
}
render() {
const { title, children } = this.props;
const { opened } = this.state;
return (
<div className="box">
<div className="boxTitle" onClick={this.toggleBox}>
{title}
</div>
{opened && children && (
<div class="boxContent">
{children}
</div>
)}
</div>
);
}
}
ReactDOM.render((
<ToggleBox title="Click me">
<div>Some content</div>
</ToggleBox>
), document.getElementById('app'));
데모 : http://jsfiddle.net/kb3gN/16688/
나는 다음과 같은 코드를 사용하고 있습니다 :
{opened && <SomeElement />}
사실 일 SomeElement
경우에만 렌더링 됩니다 opened
. JavaScript가 논리 조건을 해결하는 방식 때문에 작동합니다.
true && true && 2; // will output 2
true && false && 2; // will output false
true && 'some string'; // will output 'some string'
opened && <SomeElement />; // will output SomeElement if `opened` is true, will output false otherwise
React
무시 하겠지만 false
조건부로 일부 요소를 렌더링하는 매우 좋은 방법입니다.
어쩌면 그것은 질문을하는 누군가를 도울 수 있습니다 : React의 모든 조건부 렌더링 React의 조건부 렌더링에 대한 모든 다른 옵션에 대한 기사입니다.
어떤 조건부 렌더링을 사용해야하는지에 대한 주요 내용 :
** 다른 경우라면
- 가장 기본적인 조건부 렌더링입니다
- 초보자 친화적
- null을 반환하여 렌더 메소드에서 조기에 옵트 아웃하려면 if를 사용하십시오.
** 삼항 연산자
- if-else 문에 사용하십시오
- if-else보다 간결합니다.
** 논리 && 연산자
- 삼항 연산의 한쪽이 null을 반환 할 때 사용하십시오.
** 스위치 케이스
- 말 수가 많은
- 자체 호출 기능으로 만 인라인 가능
- 그것을 피하고 대신 열거 형을 사용하십시오.
** 열거 형
- 다른 주를 매핑하기에 완벽한
- 하나 이상의 조건을 매핑하기에 완벽한
** 다단계 / 중첩 조건부 렌더링
- 가독성을 위해 피하십시오
- 간단한 조건부 렌더링을 통해 구성 요소를 더 가벼운 구성 요소로 분할
- HOC 사용
** HOC
- 조건부 렌더링을 차단하는 데 사용
- 구성 요소는 주요 목적에 집중할 수 있습니다
** 외부 템플릿 구성 요소
- 그것들을 피하고 JSX와 JavaScript에 익숙해 지십시오
ES6을 사용하면 간단한 원 라이너로 할 수 있습니다
const If = ({children, show}) => show ? children : null
"show"는 부울이며이 클래스는
<If show={true}> Will show </If>
<If show={false}> WON'T show </div> </If>
나는 이것이 언급되지 않았다고 생각합니다. 이것은 당신의 대답과 같지만 더 간단하다고 생각합니다. 항상 표현식에서 문자열을 리턴 할 수 있으며 표현식 내에 jsx를 중첩 할 수 있으므로 인라인 표현식을 쉽게 읽을 수 있습니다.
render: function () {
return (
<div id="page">
{this.state.banner ? <div id="banner">{this.state.banner}</div> : ''}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
<script src="http://dragon.ak.fbcdn.net/hphotos-ak-xpf1/t39.3284-6/10574688_1565081647062540_1607884640_n.js"></script>
<script src="http://dragon.ak.fbcdn.net/hphotos-ak-xpa1/t39.3284-6/10541015_309770302547476_509859315_n.js"></script>
<script type="text/jsx;harmony=true">void function() { "use strict";
var Hello = React.createClass({
render: function() {
return (
<div id="page">
{this.props.banner ? <div id="banner">{this.props.banner}</div> : ''}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
});
var element = <div><Hello /><Hello banner="banner"/></div>;
React.render(element, document.body);
}()</script>
Immediately-Invoked Function Expressions ( IIFE
) if-else
이상 render callbacks
및 의 명시 성을 좋아합니다 ternary operators
.
render() {
return (
<div id="page">
{(() => (
const { banner } = this.state;
if (banner) {
return (
<div id="banner">{banner}</div>
);
}
// Default
return (
<div>???</div>
);
))()}
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
IIFE
구문에 익숙해 {expression}
져야하며 일반적인 React 구문이 있습니다. 내부에서 호출하는 함수를 작성하고 있다고 생각하면됩니다.
function() {
}()
그 안에는 괄호 안에 싸야합니다
(function() {
}())
구성 요소를 조건부 렌더링하기 위해 렌더링 소품 을 사용하는 기술도 있습니다 . 이점은 조건이 충족 될 때까지 렌더가 평가되지 않으므로 null 및 undefined 값 에 대한 걱정이 없습니다 .
const Conditional = ({ condition, render }) => {
if (condition) {
return render();
}
return null;
};
class App extends React.Component {
constructor() {
super();
this.state = { items: null }
}
componentWillMount() {
setTimeout(() => { this.setState({ items: [1,2] }) }, 2000);
}
render() {
return (
<Conditional
condition={!!this.state.items}
render={() => (
<div>
{this.state.items.map(value => <p>{value}</p>)}
</div>
)}
/>
)
}
}
전달 된 조건이 가득 찬 경우에만 무언가를 렌더링해야하는 경우 다음 구문을 사용할 수 있습니다.
{ condition && what_to_render }
이 방식의 코드는 다음과 같습니다.
render() {
const { banner } = this.state;
return (
<div id="page">
{ banner && <div id="banner">{banner}</div> }
<div id="other-content">
blah blah blah...
</div>
</div>
);
}
물론이를 수행 할 수있는 다른 유효한 방법이 있습니다.이 모든 것은 선호 사항과 경우에 달려 있습니다. 관심 이 있다면 이 기사의 React에서 조건부 렌더링을 수행하는 방법에 대한 더 많은 방법을 배울 수 있습니다 !
다른 옵션을 추가하기 만하면-커피 스크립트를 좋아하거나 견딜 수있는 경우 coffee-react를 사용하여 JSX를 작성할 수 있습니다.이 경우 커피 스크립트로 표현할 수 있고 명령문이 아닌 if / else 문을 사용할 수 있습니다.
render: ->
<div className="container">
{
if something
<h2>Coffeescript is magic!</h2>
else
<h2>Coffeescript sucks!</h2>
}
</div>
@Jack Allan의 답변을 문서에 대한 참조로 확장하십시오.
null
이러한 경우 React 기본 (빠른 시작) 설명서가 제안 합니다. 그러나 부울, 널 및 정의되지 않음도 무시 됩니다 (고급 안내서에 언급 됨).
'Programing' 카테고리의 다른 글
C #에서 둘 이상의 바이트 배열을 결합하는 가장 좋은 방법 (0) | 2020.04.18 |
---|---|
vim으로 파일 인코딩을 어떻게 변경합니까? (0) | 2020.04.18 |
UIWebView가 세로로 "튀는"것을 중지 하시겠습니까? (0) | 2020.04.18 |
Oracle SQL Developer 다중 테이블보기 (0) | 2020.04.18 |
Hibernate 및 MySQL을 사용한 생성 타임 스탬프 및 마지막 업데이트 타임 스탬프 (0) | 2020.04.18 |