使用存储作为兄弟姐妹、孩子等的单一数据源的正确方法



我已经用React/Redux做了一些不同的教程,并构建了一些较小的项目,我对使用Redux存储和检索数据的正确方法感到困惑。以下是教程如何使用商店。

  1. 从数据中读取值并将其存储到存储中
  2. 然后使用Connect和MapStateToProps将数据放置到道具中
  3. 如果必须在页面上操作数据,则将这些道具置于该状态
  4. SetState用于更新状态

这似乎是一种非常迟钝的使用单一数据源的方法,而我所期望的只是能够:

  1. 通过某种方法导入商店
  2. 使用该数据显示项目
  3. 更新数据库时操作组件上的存储

我现在遇到的问题是,当同级更新数据时,存储会更新,但不会更新同级组件。将商店映射到道具,然后将它们重新映射到状态的过程显然是个问题,我简直不敢相信这是首选方法。我在这里错过了什么?

这里有一个同级组件,当Redux存储在同级中更改时,它无法更新。this.state.question.type已更改,该更改不会提示此组件更新。这让我觉得,必须有一种更好的方式来与商店互动。或者我在其他地方有问题?感谢

import React from 'react';
import { connect } from 'react-redux';

// Import CSS
import './editQuestionStyle.css';
import '../mainCSS.css';

// Import Bootstrap Items
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Container from 'react-bootstrap/Container';
import Button from 'react-bootstrap/Button';
import InputGroup from 'react-bootstrap/InputGroup';
import FormControl from 'react-bootstrap/FormControl';
// Font Awesome Items
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCheck } from '@fortawesome/free-solid-svg-icons';
import { faPlusCircle } from '@fortawesome/free-solid-svg-icons';

// Action creators
import { editQuestion } from '../../store/actions/questions';


class AnswerOptions extends React.Component {
constructor(props) {
super(props);
this.state={};
this.state.question = props.question;
}

handleClick = (e)=>{
this.setState(prevState=>({
question : { 
...prevState.question,
answerOptions : 
prevState.question.answerOptions.concat('Answer Option')
}
}));
}

render(){
return (
<div>
<Row className="mt-large mb-3 ml-large mr-large text-center">
<Col sm={2}>
<div className="lead">
Answer Options
<FontAwesomeIcon icon={faPlusCircle}    
className="ml-small mt-tiny hover-me easy-text" 
onClick={()=>{this.handleClick()} } />
</div>
</Col>
{this.state &&
<Col sm={10}>
<Row>
<Col sm={4}>
<Container>
{this.state.question.answerOptions.length==0 ? <div className="center-me">Click plus to add option</div> : ''}
{this.state.question.answerOptions.map((answerOption, index) => (
<div>
<InputGroup key="index" className="mb-3 width-175 center-me">

{this.state.question.type=='Select' ? <InputGroup.Prepend>
<InputGroup.Radio aria-label="Correct Answer" />
</InputGroup.Prepend>:''}
<FormControl
placeholder="Enter Input"
aria-label="Tag Name"
aria-describedby="email"
ref = {this.tag+""+index}
onChange={()=>{}}
/>  
</InputGroup>
</div>
))}
</Container>
</Col>
<Col sm={8}>
<p className="text-justify">For questions where the user selects the answer, the options you enter here will be presented to them and players must choose the option you mark as correct.</p>
<p className="text-justify">For questions where the user enters the answer, the options you enter here can be variations on the correct answer such as misspellings. If what the user enters matches any of the values entered, the answer will be marked as correct.</p>
</Col>
</Row>
</Col>}
</Row>
</div>
) 
}
}

const mapStateToProps = (state, ownProps)=>{
const questionId = ownProps.questionId;
const questions = state.firestore.data.questions;
const question = questions ? questions[questionId] : null;
return {
question:question,
questionId : questionId
}
}

const mapDispatchToProps = (dispatch) => {
return {
editQuestion: (question, questionId) => dispatch(editQuestion(question, questionId))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(AnswerOptions);

为什么用props.question初始化本地状态?你不必做这样的事。您的render()方法是使用本地状态,该状态曾在构造函数中用redux存储值初始化过一次。在那之后,即使您的兄弟姐妹也更新了存储,也没有理由更新UI,因为您不直接使用mapStateToProps中的值,而是使用在创建组件类时初始化的本地状态。

让actions\dispatchers更新redux存储&在CCD_ 5方法中直接使用CCD_。

handleClick中,您不是存储的dispatch新值。它只是更新当地的状态。与其这样做,您应该调用dispatcher或负责更新相关reduceraction。一旦你这样做,CCD_ 11将改变&将强制重新渲染必要的零件。

最后,正如Dan Abramov所说,

"我想修改一下:在出现问题之前不要使用Redux香草React">

此外,根据的Pete Hunt

"你会知道什么时候需要Flux。如果你不确定自己是否需要它,你不需要它;

如果你不了解Redux,这是你能找到的最好的解释之一https://youtu.be/3sjMRS1gJys

请注意,react-redux只是一个将Redux与React一起使用的适配器。

最后,我鼓励您使用带钩子的功能组件,这将完全消除高阶组件(connect(、mapStateToPros&mapDispatchToProps

最新更新