javascript - React-Redux - 调用操作时出现 TypeError: String.prototype.property called on null or undefined
问题描述
我正在尝试实现 Redux 来动态控制我的导航栏链接。我在导航栏链接上有一个“链接活动”功能,该功能根据显示的页面而处于活动状态。通过我在应用程序中访问不同页面的所有链接,使用 Redux 商店处理哪些导航链接处于活动状态似乎更容易。
我收到此错误:TypeError: String.prototype.link called on null or undefined
当我调用我的一项操作时,更新商店的链接应该处于活动状态。
这是我的实施,从我的行动开始:
navbar_actions.js:
const Types = {
NAV_LINK_ACTIVE: 'NAV_LINK_ACTIVE',
};
const navlinkActive = (link) => ({
type: Types.NAV_LINK_ACTIVE,
payload: link,
});
export default {
navlinkActive,
Types,
};
navbar_reducers.js:
import NAVBAR_ACTIONS from '../actions/navbar_actions';
import _ from 'lodash';
const defaultState = {
link: '',
};
const navbarReducer = (state = defaultState, action) => {
switch (action.type) {
case NAVBAR_ACTIONS.Types.NAV_LINK_ACTIVE: {
let link = action.payload;
return link;
}
default:
return state;
}
};
export default navbarReducer;
商店.js:
import { createStore } from 'redux';
import navbarReducer from '../reducers/navbar_reducers';
export default function configureStore(initialState) {
const store = createStore(navbarReducer, initialState);
return store;
}
这是导航栏用来呈现链接的我的链接组件(该组件只需要访问存储状态):
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
//Redux
import NAVBAR_ACTIONS from '../../../../modules/actions/navbar_actions';
import { connect } from 'react-redux';
import propTypes from 'prop-types';
//Styles
import { LinkContainer, LinkWrap } from './styles';
//Notes
//@Required: links array passed as props. Each object in the links array should contain a path and name property. Refer to propTypes definition at the bottom.
const Links = (props) => {
const [clickedLink, setClickedLink] = useState('Home');
useEffect(() => {
if (props.link.length === 0) return;
else setClickedLink(props.link);
}, [props.link]);
return (
<LinkContainer>
{props.links.map((link, i) => (
<LinkWrap isActive={link.name === clickedLink ? true : false} key={i}>
<Link
to={link.path}
onClick={() => {
setClickedLink(link.name);
}}
>
{link.name}
</Link>
</LinkWrap>
))}
</LinkContainer>
);
};
const mapStateToProps = (state) => ({
link: state.link,
});
export default connect(mapStateToProps, null)(Links);
Links.propTypes = {
links: propTypes.arrayOf(
propTypes.shape({
path: propTypes.string.isRequired,
name: propTypes.string.isRequired,
})
).isRequired,
};
通过useEffect()
钩子,任何时候props.link
更新,它都会在Links
组件状态中更新。这就是我认为store
每次更改时我都会从状态中获取更新链接的方式。可能是错的,但这是我的尝试。
这是我在其中调用操作的组件:
import React from 'react';
//Redux
import { connect } from 'react-redux';
import NAVBAR_ACTIONS from '../../../modules/actions/navbar_actions';
import { Link } from 'react-router-dom';
//Styles
import {
HomePageHero,
LatestPostsHeader,
HeroHeader,
HeroText,
HeroViewPosts,
} from './styles';
//Components
import Page from '../../Layout/Page';
import Blog from '../Blog/Blog';
import SocialLinks from './Components/SocialMediaLinks/SocialLinks';
const Home = (props) => {
console.log(props);
return (
<Page noheader={true} pageTitle="">
<HomePageHero>
<HeroHeader>
<p>Maison</p>
<div></div>
<p>Moa</p>
</HeroHeader>
<HeroText>
<p>
Loreum Ipsum
</p>
</HeroText>
<HeroViewPosts>
<Link
to="/blog"
onClick={() => {
props.navlinkActive('blog');
console.log(props);
}}
>
View My Blog
</Link>
</HeroViewPosts>
<SocialLinks />
</HomePageHero>
<LatestPostsHeader>
<h3>Latest Posts</h3>
</LatestPostsHeader>
<Blog pageTitle="Latest Posts" noheader={true} />
</Page>
);
};
const mapDispatchToProps = (dispatch) => ({
navlinkActive: (link) => dispatch(NAVBAR_ACTIONS.navlinkActive(link)),
});
export default connect(null, mapDispatchToProps)(Home);
这是我在调用时遇到的错误的实际屏幕截图props.navlinkActive()
:
我对这个错误有点不知所措,因为我真的找不到任何关于它的“Redux”。提前感谢您的帮助和洞察力!
解决方案
最终解决了这个问题。错误来自我的Links.js
组件:
特别是这里:
useEffect(() => {
if (props.link.length === 0) return;
else setClickedLink(props.link);
}, [props.link]);
props.link
未定义。这是因为我没有从navbar_reducer.js
.
这就是减速器应该如何返回状态(cloneDeep()
在此处使用 lodash):
const navbarReducer = (state = defaultState, action) => {
switch (action.type) {
case NAVBAR_ACTIONS.Types.NAV_LINK_ACTIVE: {
let link = action.payload;
let newState = _.cloneDeep(state);
newState.link = link;
return newState;
}
default:
return state;
}
};
老办法。我正在修改 reducer 中的现有状态,而不是返回具有必要更改的新状态副本。我直接改变了现有状态,这样做时,Redux 不会检测到更改,因此任何connect()
用于访问存储的组件都不会得到更新。
现在一切都按预期工作。这是 React 中的第一条规则。不要改变状态!我应该知道的。确保您始终获得状态的深层副本,然后对该副本进行更改。
推荐阅读
- c# - 如何根据单元格数据长度c#制作表格边框长度?
- javascript - 创建一个函数并在 node.js 中的另一个文件上调用它
- select - 我可以在基于第三列拆分后写入特定列吗?
- javascript - 检测由于下载栏(chrome、latest edge、firefox)而导致的窗口调整大小与一般窗口调整大小
- javascript - 如果我们想在一行中插入多张通过拖放上传的图片,我们该怎么办?
- php - 在本地主机上的 Apache 中将根文件夹设置为子文件夹,这也将在生产服务器上工作
- python - 在 macos 上使用 python 2.7.10 的 Tkinter notebook 的不同选项卡中,滚动条无法正常工作
- python - 我可以将 django_rest 与 django-tenants 一起使用吗?
- python - 合并数据框并保留列?
- go - Golang fmt printf 右填充