在 React/Redux 中无需路由即可导航组件
Navigating components without routing in React/Redux
这可能会令人费解,所以请耐心等待。我刚刚开始学习 React/Redux 和管理状态。我想构建一个不使用路由的小应用程序,如下所示:
与安装向导没什么不同。
系统会提示用户在每一页上回答一个问题,然后按一个按钮前进或后退。最后,用户将看到他们的答案列表。
我想象状态看起来像这样:
{
steps: [
{ prompt: 'Question in step 1', answer: null },
{ prompt: 'Question in step 2', answer: null },
{ prompt: 'Question in step 3', answer: null }
],
currentStepNumber: 0,
currentStepData: { prompt: 'Question in step 1', answer: null }
}
前进 forwards/backwards 应该 increment/decrement currentStepNumber
而 currentStepData
应该显示,比如 steps[0]
。此外,应在导航时保存响应。
最后,所有结果都应该在最终 "page."
上可见
我真的很困惑如何通过简单地在组件和容器之间传递 props 来在没有路由的情况下做到这一点。
上面的状态对象是一个尝试,看起来它可能有效,但我觉得我没有得到它。
具体问题:
- 如何在 "navigation" 没有路由的情况下 show/hide 组件?
- 在到达最后一步之前,是否应该一直隐藏结果容器?
- 如何设计状态,以便知道步骤 N 是向导中的最后一步,因此需要显示结果容器?
How to show/hide components upon "navigation" without routes?
您应该使用所谓的 conditional rendering。在您的情况下,可以在没有路由器的情况下像这样实现组件:
const Step1 = ({prompt, onNextStep}) => (
<div>
<h1>{prompt}</h1>
<button type="button" className="btn btn-info" onClick={onNextStep}>Next</button>
</div>
);
const Step2 = ({prompt, onNextStep, onPrevStep}) => (
<div>
<h1>{prompt}</h1>
<button type="button" className="btn btn-info" onClick={onPrevStep}>Prev</button>
<button type="button" className="btn btn-info" onClick={onNextStep}>Next</button>
</div>
);
const Step3 = ({prompt, onPrevStep, onSubmit}) => (
<div>
<h1>{prompt}</h1>
<button type="button" className="btn btn-info" onClick={onPrevStep}>Prev</button>
<button type="button" className="btn btn-info" onClick={onSubmit}>Submit</button>
</div>
);
const Results = ({prompt, children, onReset}) => (
<div>
<h1>{prompt}</h1>
{children}
<button type="button" className="btn btn-info" onClick={onReset}>Reset</button>
</div>
);
class App extends React.Component {
state = {
step: 1,
steps: [
{
prompt: 'Prompt 1',
answer: ''
},
{
prompt: 'Prompt 2',
answer: ''
},
{
prompt: 'Prompt 3',
answer: ''
},
],
};
onNextStep = () => this.setState({
step: this.state.step + 1
});
onPrevStep = () => this.setState({
step: this.state.step - 1
});
onSubmit = () => this.setState({
step: null
});
onReset = () => this.setState({
step: 1
});
render() {
const { step, steps } = this.state;
const { prompt } = step ? steps[step-1] : '';
if (step === 1) {
return (
<Step1
prompt={prompt}
onNextStep={this.onNextStep}
/>
);
}
if (step === 2) {
return (
<Step2
prompt={prompt}
onNextStep={this.onNextStep}
onPrevStep={this.onPrevStep}
/>
);
}
if (step === 3) {
return (
<Step3
prompt={prompt}
onPrevStep={this.onPrevStep}
onSubmit={this.onSubmit}
/>
);
}
if (step === null) {
return (
<Results
prompt="These are results"
onReset={this.onReset}
>
<p>Drop results here as children</p>
</Results>
);
}
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.css" />
<div id="root"></div>
Should the result container simply be hidden the entire time until the
last step is reached?
同样,遵循 条件渲染 最佳实践,您可能不想 'hide',而是在满足特定条件时渲染结果容器。在我的示例中,结果容器在状态变量 step
等于 null
.
时呈现
How do I design the state so that I know step N is the last step in
the wizard and thus results container need to be displayed?
您的状态设计似乎没问题。您可以通过简单地比较 this.state.steps.length
和 this.state.step
来检查您是否到达了最后一步。如果它们相等,则您已到达最后一步。
这可能会令人费解,所以请耐心等待。我刚刚开始学习 React/Redux 和管理状态。我想构建一个不使用路由的小应用程序,如下所示:
与安装向导没什么不同。
系统会提示用户在每一页上回答一个问题,然后按一个按钮前进或后退。最后,用户将看到他们的答案列表。
我想象状态看起来像这样:
{
steps: [
{ prompt: 'Question in step 1', answer: null },
{ prompt: 'Question in step 2', answer: null },
{ prompt: 'Question in step 3', answer: null }
],
currentStepNumber: 0,
currentStepData: { prompt: 'Question in step 1', answer: null }
}
前进 forwards/backwards 应该 increment/decrement currentStepNumber
而 currentStepData
应该显示,比如 steps[0]
。此外,应在导航时保存响应。
最后,所有结果都应该在最终 "page."
我真的很困惑如何通过简单地在组件和容器之间传递 props 来在没有路由的情况下做到这一点。
上面的状态对象是一个尝试,看起来它可能有效,但我觉得我没有得到它。
具体问题:
- 如何在 "navigation" 没有路由的情况下 show/hide 组件?
- 在到达最后一步之前,是否应该一直隐藏结果容器?
- 如何设计状态,以便知道步骤 N 是向导中的最后一步,因此需要显示结果容器?
How to show/hide components upon "navigation" without routes?
您应该使用所谓的 conditional rendering。在您的情况下,可以在没有路由器的情况下像这样实现组件:
const Step1 = ({prompt, onNextStep}) => (
<div>
<h1>{prompt}</h1>
<button type="button" className="btn btn-info" onClick={onNextStep}>Next</button>
</div>
);
const Step2 = ({prompt, onNextStep, onPrevStep}) => (
<div>
<h1>{prompt}</h1>
<button type="button" className="btn btn-info" onClick={onPrevStep}>Prev</button>
<button type="button" className="btn btn-info" onClick={onNextStep}>Next</button>
</div>
);
const Step3 = ({prompt, onPrevStep, onSubmit}) => (
<div>
<h1>{prompt}</h1>
<button type="button" className="btn btn-info" onClick={onPrevStep}>Prev</button>
<button type="button" className="btn btn-info" onClick={onSubmit}>Submit</button>
</div>
);
const Results = ({prompt, children, onReset}) => (
<div>
<h1>{prompt}</h1>
{children}
<button type="button" className="btn btn-info" onClick={onReset}>Reset</button>
</div>
);
class App extends React.Component {
state = {
step: 1,
steps: [
{
prompt: 'Prompt 1',
answer: ''
},
{
prompt: 'Prompt 2',
answer: ''
},
{
prompt: 'Prompt 3',
answer: ''
},
],
};
onNextStep = () => this.setState({
step: this.state.step + 1
});
onPrevStep = () => this.setState({
step: this.state.step - 1
});
onSubmit = () => this.setState({
step: null
});
onReset = () => this.setState({
step: 1
});
render() {
const { step, steps } = this.state;
const { prompt } = step ? steps[step-1] : '';
if (step === 1) {
return (
<Step1
prompt={prompt}
onNextStep={this.onNextStep}
/>
);
}
if (step === 2) {
return (
<Step2
prompt={prompt}
onNextStep={this.onNextStep}
onPrevStep={this.onPrevStep}
/>
);
}
if (step === 3) {
return (
<Step3
prompt={prompt}
onPrevStep={this.onPrevStep}
onSubmit={this.onSubmit}
/>
);
}
if (step === null) {
return (
<Results
prompt="These are results"
onReset={this.onReset}
>
<p>Drop results here as children</p>
</Results>
);
}
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.css" />
<div id="root"></div>
Should the result container simply be hidden the entire time until the last step is reached?
同样,遵循 条件渲染 最佳实践,您可能不想 'hide',而是在满足特定条件时渲染结果容器。在我的示例中,结果容器在状态变量 step
等于 null
.
How do I design the state so that I know step N is the last step in the wizard and thus results container need to be displayed?
您的状态设计似乎没问题。您可以通过简单地比较 this.state.steps.length
和 this.state.step
来检查您是否到达了最后一步。如果它们相等,则您已到达最后一步。