React 子组件仅在刷新时更新
Posted
技术标签:
【中文标题】React 子组件仅在刷新时更新【英文标题】:React child component only updates on refresh 【发布时间】:2021-11-14 01:41:51 【问题描述】:我在 React 中使用函数组件,我有一个名为 'ChallengeItem' 的父组件和一个名为 'ChallengeItem' 的子组件。
'Challenges' 组件调用一个名为 'getAllChallenges' 的操作,该操作从我的数据库中获取所有挑战并通过它们进行映射:
import React, Fragment, useEffect from 'react';
import PropTypes from 'prop-types';
import connect from 'react-redux';
import getAllChallenges from '../../actions/challenge';
import Loading from '../layout/Loading';
import ChallengeItem from './ChallengeItem';
const Challenges = (
getAllChallenges,
challenge: challenges, loading ,
progress,
) =>
useEffect(() =>
getAllChallenges();
, [getAllChallenges]);
return loading ? (
<Loading />
) : (
<Fragment>
<h1 className='text-center mt-5'>Course Syllabus</h1>
<div className='row mt-5 mx-5 row-cols-1 row-cols-md-2 row-cols-lg-4 g-4'>
challenges.map((challenge) => (
<ChallengeItem key=challenge._id challenge=challenge />
))
</div>
</Fragment>
);
;
Challenges.propTypes =
getAllChallenges: PropTypes.func.isRequired,
challenge: PropTypes.object.isRequired,
progress: PropTypes.object.isRequired,
;
const mapStateToProps = (state) => (
challenge: state.challenge,
progress: state.auth.user.progress,
);
export default connect(mapStateToProps, getAllChallenges )(Challenges);
'ChallengeItem' 组件返回一个动态显示个人挑战信息的 Fragment:
import React, Fragment from 'react';
import PropTypes from 'prop-types';
import connect from 'react-redux';
import Link from 'react-router-dom';
const ChallengeItem = (
auth,
user: progress ,
challenge: _id, section_name, section_no, challenge_no, challenge_name ,
) => (
<Fragment>
<div className='col'>
<div className='card challengeCard'>
<div className='card-body'>
<h5 className='card-title'>
Section section_no, Challenge challenge_no
</h5>
<p className='card-text'>
section_name- challenge_name
</p>
isChallengeUnlocked(_id, progress) ? (
<Link
to=`/challenge/$_id`
className='btn btn-secondary pinkBtn'
>
Unlocked <i className='fas fa-lock-open'></i>
</Link>
) : (
<button className='btn btn-secondary pinkBtn' disabled>
Locked <i className='fas fa-lock'></i>
</button>
)
</div>
</div>
</div>
</Fragment>
);
ChallengeItem.propTypes =
challenge: PropTypes.object.isRequired,
auth: PropTypes.object.isRequired,
;
const mapStateToProps = (state) => (
auth: state.auth,
user: state.auth.user,
);
export default connect(mapStateToProps)(ChallengeItem);
function isChallengeUnlocked(_id, progress)
for (const value of progress)
if (value.challenge === _id)
return true;
return false;
'ChallengeItem' 组件中还有一个函数,它根据用户的进度确定他们是否已解锁特定挑战。
如果他们解锁了挑战,它将显示出来,并且用户可以点击链接导航到该挑战。
如果他们未解锁了挑战,则会显示该挑战,但此挑战的按钮将禁用,用户将无法点击它。
我遇到的问题是,当用户新解锁挑战并且用户导航到挑战页面以查看所有锁定/解锁的挑战时,新解锁的挑战在页面上显示为锁定且仅当页面刷新时,新解锁的挑战会显示为解锁状态。
当子组件更新时如何获得重新渲染的挑战?
我在网上搜索了一个答案,似乎很多人都在说为子组件设置一个密钥以便它重新渲染,但我已经在这样做了。我不确定是什么问题,也许这是一个单独的问题。
非常感谢您在此阶段提供的任何帮助,谢谢!
编辑:
// getAllChallenges action
export const getAllChallenges = () => async (dispatch) =>
try
const res = await axios.get(`/api/challenge/all`);
dispatch(
type: GET_CHALLENGES,
payload: res.data,
);
catch (err)
dispatch(
type: CHALLENGE_ERROR,
payload: msg: err.response.statusText, status: err.response.status ,
);
;
// UPDATE_PROGRESS reducer
case UPDATE_PROGRESS:
return
...state,
user:
...state.user,
progress: payload,
,
loading: false,
;
【问题讨论】:
目前,您只能在开头抓取。您需要将进度传递给函数,然后将其添加到依赖数组中。基本上,如果进度更改触发获取。 我尝试将 Challenge 组件中的 useEffect 更改为:useEffect(() => getAllChallenges(); , [progress]);当进度状态发生变化时尝试加载所有挑战,但它仍然给我同样的问题getAllChallenges
操作看起来如何?
嗨 Seshkebab,我删除了我的答案,对此感到抱歉。我错过了你正在使用 redux。顺便说一句,当您发现挑战已解锁时,您是否可以不发送操作。这将更新存储在 redux 存储中的challenges
?
@merko 我已经更新了我的答案,附带了 getAllChallenges 操作
【参考方案1】:
由于ChallengeItem
是一个 Redux 连接组件,它仅依赖于 Redux 状态,因此您需要设置 pure: false
in the connect()
options:
export default connect(mapStateToProps, null, null, pure: false)(ChallengeItem);
【讨论】:
谢谢,我试过了,但对我不起作用以上是关于React 子组件仅在刷新时更新的主要内容,如果未能解决你的问题,请参考以下文章
是否可以仅在 react-router 转换时仅重新安装新的子组件