【问题标题】:useEffect does not fire redux action until page is refreshed在页面刷新之前,useEffect 不会触发 redux 操作
【发布时间】:2020-08-11 23:20:33
【问题描述】:

我的 useEffect 函数在第一页加载时不会触发 redux 操作调用,我只是收到一个错误,上面写着 TypeError: Cannot read property 'length' of undefined 这可能是因为状态尚未加载,因为我猜该操作从未被触发。但是当我重新加载页面时,它工作正常,组件也加载没有任何问题。

这是我的反应组件:

const BooksById = ({bookdetails:{bookDetails,loading},getBookById,match}) =>{
    useEffect(()=>{
        console.log("action fired")
        getBookById(match.params.genre)
    },[getBookById,match.params.genre])

const [modal, setModal] = useState(false);

const toggle = () => setModal(!modal);
  
const [formData, setFormData] = useState({
    status: '',
    rating: '',
    review: ''
});
const {status, rating, review} = formData;

const onChange = e => setFormData({...formData, [e.target.name]:e.target.value})

const onSubmit = e => {
    e.preventDefault();
   console.log(status, rating, review);
};
return (
(
    <Fragment>
    {loading ? (
        <Spinner />
      ) : (
    <Fragment>
            <Container style={{paddingTop: "1.5rem"}}>
                <Card>
                    <Row>
                        <aside className="col-sm-3 border-right">
                            <article className="gallery-wrap"> 
                                <div className="img-wrap">
                                <center>
                                    <Media src="https://via.placeholder.com/190x320"/>
                                </center>
                                </div>
                                <center>
                                    <Button color="primary" onClick={toggle}><i class="fa fa-book"></i> Add to shelf </Button>
                                    <Modal isOpen={modal} toggle={toggle}>
                                        <ModalHeader toggle={toggle}>Add to shelf</ModalHeader>
                                        <ModalBody>
                                            <Form onSubmit={e => onSubmit(e)}>
                                                <FormGroup row>
                                                <Label for="exampleSelect" sm={2}>Status</Label>
                                                    <Col sm={6}>
                                                        <Input type="select" name="Add to" id="exampleSelect" placeholder="* select a shelf" value={status} onChange={e => onChange(e)} required>
                                                            <option value=''></option>
                                                            <option value='plan to read'>plan to read</option>
                                                            <option value='reading'>reading</option>
                                                            <option value='completed'>completed</option>
                                                            <option value='dropped'>dropped</option>
                                                        </Input>
                                                    </Col>
                                                </FormGroup>
                                                <FormGroup row>
                                                <Label for="exampleSelect" sm={2}>Rating</Label>
                                                    <Col sm={4}>
                                                        <Input type="select" name="rating" placeholder="(optional)" id="exampleSelect"  value={rating} onChange={e => onChange(e)}>
                                                            <option value =''>(optional)</option>
                                                            <option value ='1'>1</option>
                                                            <option value ='2'>2</option>
                                                            <option value ='3'>3</option>
                                                            <option value ='4'>4</option>
                                                            <option value ='5'>5</option>
                                                        </Input>
                                                    </Col>
                                                </FormGroup>
                                                <FormGroup row>
                                                    <Label for="exampleText" sm={2}>Review</Label>
                                                    <Col sm={9}>
                                                        <Input type="textarea" name="review" placeholder="(optional)" id="exampleText" value={review} onChange={e => onChange(e)} />
                                                    </Col>
                                                </FormGroup>
                                                <Button type ="submit" color="primary" >save</Button>{' '}
                                                <Button color="secondary" onClick={toggle}>Cancel</Button>
                                            </Form>                                             
                                        </ModalBody>
                                        
                                    </Modal>
                                </center>
                            </article> 
                        </aside>
                        <aside class="col-sm-7">
                            <article class="card-body p-5">
                                    <h3 class="title mb-3">{bookDetails.bookName}</h3>
                                    <dl class="param param-feature">
                                        <dt>Rating</dt>
                                        <dd>
                                            <span class="float-center"><i class="text-warning fa fa-star"></i></span>
                                            <span class="float-center"><i class="text-warning fa fa-star"></i></span>
                                            <span class="float-center"><i class="text-warning fa fa-star"></i></span>
                                            {' '}3.05
                                        </dd>
                                    </dl>
                                    <dl class="item-property">
                                        <dt>Description</dt>
                                        <dd><p>{bookDetails.bookDescription}</p></dd>
                                    </dl>
                                    <dl class="param param-feature">
                                        <dt>Author</dt>
                                        <dd>someone</dd>
                                    </dl>  
                                    <dl class="param param-feature">
                                        <dt>Publish date</dt>
                                        <dd>some date</dd>
                                    </dl>  
                                    <dl class="param param-feature">
                                        <dt>Genres</dt>
                                        <dd>{
                                            bookDetails.bookGenre.map(x=>x + ', ')}</dd>
                                    </dl>  
                            </article> 
                        </aside> 
                    </Row>
                </Card>
            </Container>
            {/* review container */}
            <Container style={{paddingTop: "1.5rem",paddingBottom: "1.5rem"}}>
            <hr/>
            <h2 style={{paddingTop: "1.5rem",paddingBottom: "1.5rem"}}>Reviews</h2>
            <Card>
                <CardBody>
                    <Row>
                        <Col md="12">
                            <p>
                                <strong>some one</strong>
                                <span class="float-right"><i class="text-warning fa fa-star"></i></span>
                                <span class="float-right"><i class="text-warning fa fa-star"></i></span>
                                <span class="float-right"><i class="text-warning fa fa-star"></i></span>
                            </p>
                            <div class="clearfix"></div>
                            <p>Lorem Ipsum is simply dummy text of the pr make  but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
                        </Col>
                    </Row>
                </CardBody>
            </Card>
        </Container>
    </Fragment> )}
</Fragment>
)
)

BooksById.propTypes={
    bookdetails: PropTypes.object.isRequired,
    getBookById: PropTypes.func.isRequired
}

const mapStateToProps = state => ({
    bookdetails: state.bookdetails
})

export default connect(mapStateToProps,{getBookById}) (BooksById);

这是我要调用的操作:

export const getBookById = (id) => dispatch => {
    axios.get(`/api/booksDetails/${id}`)
         .then(res=>{
             dispatch({
                 type: GET_BOOKBYID,
                 payload: res.data
             })
         })
         .catch(err=>{
            dispatch({
                type: BOOKDETAILS_FAIL,
                payload: { msg: err.response.statusText, status: err.response.status }
            })
        })
}

这里是减速器:

export default function (state = initialState, action) {
    const { type, payload } = action;
  
    switch (type) {
        case GET_BOOKDETAILS:
        case GET_BOOKBYGENRE:
            return{
                ...state,
                loading: false,
                bookDetails: payload
            }
        case GET_BOOKBYID:
                return{
                    ...state,
                    loading: false,
                    bookDetails: payload
                }
        case BOOKDETAILS_FAIL:
            return{
                ...state,
                loading: false,
                bookDetails: payload
            }
        default:
            return state;
    }

}

请帮我改一下,谢谢。

【问题讨论】:

  • 错误是TypeError: Cannot read property 'length' of undefined,但您发布的代码没有尝试从任何地方获取length。也许在获取 bookDetails.length 之前尝试将初始状态的 bookDetails 设置为数组或正确使用 loading (我想这就是你想要做的,但缺少代码)。通常你会检查 redux 开发工具,看看是否使用正确的值调度了正确的操作,以及它们是否会导致正确的更改。
  • @HMR 我现在已经上传了代码,实际上文件太大了所以我没有上传它,而且我正在使用 redux devtools 并且在我重新加载之前操作根本不会触发该页面,如果加载错误,我还添加了一个微调器,但它仍然无法正常工作
  • 仍然没有看到导致错误的行。 Redux devtools 应该在调度 init 操作时向您显示状态,以便您可以确保正确设置加载并且您没有将加载映射到连接中的道具。

标签: reactjs redux react-redux


【解决方案1】:

首先我建议你使用更简单的 react redux hooks for the documentation

首先我建议您采取所有措施并将其放在一个文件中,而不是这样做

 dispatch({
                 type: GET_BOOKBYID,
                 payload: res.data
             })

因为它会让您的生活更轻松,并且可以查看使用此功能的人以及在哪里出现问题 关于您的问题,我认为在连接参数中您需要像这样传递它:

    const mapDispatchToProps = dispatch => {
    return {
        onUpdate: (employee) => dispatch(actionTypes.UpdateEmployeeFetch(employee))
    }
}

我记得你需要像这样传递它,否则什么都不会发生(这也发生在我身上!) 如果你决定使用钩子版本,你可以这样做:

const dispatch = useDispatch();
const addToFavorite = useCallback(
    (key) => dispatch(actionCreators.addExistedCity(key)),
    [dispatch]
)

 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-03
    • 2021-10-08
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    相关资源
    最近更新 更多