8.8 KiB
id, title, challengeType, forumTopicId, dashedName
id | title | challengeType | forumTopicId | dashedName |
---|---|---|---|---|
5a24c314108439a4d4036188 | props から条件付きでレンダーする | 6 | 301405 | render-conditionally-from-props |
--description--
So far, you've seen how to use if/else
, &&
, and the ternary operator (condition ? expressionIfTrue : expressionIfFalse
) to make conditional decisions about what to render and when. However, there's one important topic left to discuss that lets you combine any or all of these concepts with another powerful React feature: props. Using props to conditionally render code is very common with React developers — that is, they use the value of a given prop to automatically make decisions about what to render.
このチャレンジでは、props に基づいてレンダー処理を決定する子コンポーネントを設定します。 また、三項演算子も使用しますが、前のチャレンジで説明した他のいくつかの概念が、このチャレンジでも同じように役立つかもしれません。
--instructions--
コードエディターに 2 つのコンポーネントがあって、一部が定義されています。1 つは GameOfChance
という親で、もう 1 つは Results
という子です。 これらを使用して、ユーザーがボタンを押して勝ったか負けたかを表示する簡単なゲームを作成します。
まず、実行のたびに異なる値をランダムに返す簡単な式が必要です。 これには Math.random()
を使用できます。 このメソッドは、呼び出されるたびに 0
(含む) ~ 1
(含まない) の間の値を返します。 そのため、確率を 50/50 にする場合は Math.random() >= .5
という式を使用します。 統計的に言えば、この式は 50% の確率で true
を返し、残りの 50% の確率で false
を返します。 render メソッドで、null
の部分を前述の式に置き換えて変数宣言を完成させてください。
これで、コードでランダムな決定を行うのに使用できる式ができました。 次に、この式を実装する必要があります。 Results
コンポーネントを GameOfChance
の子としてレンダーし、expression
を fiftyFifty
という prop として渡してください。 Results
コンポーネントで、GameOfChance
から渡される fiftyFifty
prop に基づいて、You Win!
または You Lose!
というテキストを使用して h1
要素をレンダーする三項式を記述してください。 最後に、handleClick()
メソッドで、各ターンを正しくカウントし、ユーザーが自分のプレイした回数を確認できるようにしてください。 こうすることで、2 連勝または 2 連敗した場合にコンポーネントが実際に更新されたことをユーザーに伝えることもできます。
--hints--
GameOfChance
コンポーネントが存在し、ページにレンダーする必要があります。
assert.strictEqual(
Enzyme.mount(React.createElement(GameOfChance)).find('GameOfChance').length,
1
);
GameOfChance
から単一の button
要素を返します。
assert.strictEqual(
Enzyme.mount(React.createElement(GameOfChance)).find('button').length,
1
);
GameOfChance
から Results
コンポーネントの単一のインスタンスを返します。これには fiftyFifty
という prop があります。
assert(
Enzyme.mount(React.createElement(GameOfChance)).find('Results').length ===
1 &&
Enzyme.mount(React.createElement(GameOfChance))
.find('Results')
.props()
.hasOwnProperty('fiftyFifty') === true
);
GameOfChance
の state を初期化し、counter
のプロパティを値 1
に設定します。
assert.strictEqual(
Enzyme.mount(React.createElement(GameOfChance)).state().counter,
1
);
GameOfChance
コンポーネントを初めて DOM にレンダーするときに、p
要素をその内側のテキスト Turn: 1
とともに返します。
assert.strictEqual(
Enzyme.mount(React.createElement(GameOfChance)).find('p').text(),
'Turn: 1'
);
ボタンがクリックされるたびに、カウンターの state の値を 1 ずつ増やし、テキスト Turn: N
が含まれている DOM に単一の p
要素をレンダーします。ここで N
はカウンターの state の値です。
(() => {
const comp = Enzyme.mount(React.createElement(GameOfChance));
const simulate = () => {
comp.find('button').simulate('click');
};
const result = () => ({
count: comp.state('counter'),
text: comp.find('p').text()
});
const _1 = () => {
simulate();
return result();
};
const _2 = () => {
simulate();
return result();
};
const _3 = () => {
simulate();
return result();
};
const _4 = () => {
simulate();
return result();
};
const _5 = () => {
simulate();
return result();
};
const _1_val = _1();
const _2_val = _2();
const _3_val = _3();
const _4_val = _4();
const _5_val = _5();
assert(
_1_val.count === 2 &&
_1_val.text === 'Turn: 2' &&
_2_val.count === 3 &&
_2_val.text === 'Turn: 3' &&
_3_val.count === 4 &&
_3_val.text === 'Turn: 4' &&
_4_val.count === 5 &&
_4_val.text === 'Turn: 5' &&
_5_val.count === 6 &&
_5_val.text === 'Turn: 6'
);
})();
GameOfChance
コンポーネントが初めて DOM にマウントされたら、その後ボタンがクリックされるたびに、You Win!
または You Lose!
のいずれかをランダムにレンダーする単一の h1
要素を返します。
(() => {
const comp = Enzyme.mount(React.createElement(GameOfChance));
const simulate = () => {
comp.find('button').simulate('click');
};
const result = () => ({
h1: comp.find('h1').length,
text: comp.find('h1').text()
});
const _1 = result();
const _2 = () => {
simulate();
return result();
};
const _3 = () => {
simulate();
return result();
};
const _4 = () => {
simulate();
return result();
};
const _5 = () => {
simulate();
return result();
};
const _6 = () => {
simulate();
return result();
};
const _7 = () => {
simulate();
return result();
};
const _8 = () => {
simulate();
return result();
};
const _9 = () => {
simulate();
return result();
};
const _10 = () => {
simulate();
return result();
};
const _2_val = _2();
const _3_val = _3();
const _4_val = _4();
const _5_val = _5();
const _6_val = _6();
const _7_val = _7();
const _8_val = _8();
const _9_val = _9();
const _10_val = _10();
const __text = new Set([
_1.text,
_2_val.text,
_3_val.text,
_4_val.text,
_5_val.text,
_6_val.text,
_7_val.text,
_8_val.text,
_9_val.text,
_10_val.text
]);
const __h1 = new Set([
_1.h1,
_2_val.h1,
_3_val.h1,
_4_val.h1,
_5_val.h1,
_6_val.h1,
_7_val.h1,
_8_val.h1,
_9_val.h1,
_10_val.h1
]);
assert(__text.size === 2 && __h1.size === 1);
})();
--seed--
--after-user-code--
ReactDOM.render(<GameOfChance />, document.getElementById('root'));
--seed-contents--
class Results extends React.Component {
constructor(props) {
super(props);
}
render() {
{/* Change code below this line */}
return <h1></h1>;
{/* Change code above this line */}
}
}
class GameOfChance extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 1
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => {
// Complete the return statement:
return {
counter: prevState
}
});
}
render() {
const expression = null; // Change this line
return (
<div>
<button onClick={this.handleClick}>Play Again</button>
{/* Change code below this line */}
{/* Change code above this line */}
<p>{'Turn: ' + this.state.counter}</p>
</div>
);
}
}
--solutions--
class Results extends React.Component {
constructor(props) {
super(props);
}
render() {
return <h1>{this.props.fiftyFifty ? 'You Win!' : 'You Lose!'}</h1>;
}
}
class GameOfChance extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 1
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => {
return {
counter: prevState.counter + 1
}
});
}
render() {
const expression = Math.random() >= 0.5;
return (
<div>
<button onClick={this.handleClick}>Play Again</button>
<Results fiftyFifty={expression} />
<p>{'Turn: ' + this.state.counter}</p>
</div>
);
}
}