我正在visual studio 2017提供的reactjs模板中创建一个小型Web应用程序。我陷入了一种情况,我希望将一个函数作为状态传递给子组件,然后通过子组件调用该函数。我有一个标题组件,我有一个名为 setLogInTrue()的方法,我想传递给我的SignIn组件。以下是我的代码: -
Header.tsx
class HeaderState {
isLoggedIn: boolean;
}
export class Header extends React.Component<HeaderProps, HeaderState> {
constructor() {
super()
this.state = ({ isLoggedIn: false });
this.setLogInTrue= this.setLogInTrue.bind(this);
}
setLogInTrue() {
this.setState({ isLoggedIn: true });
}
public render(){
//Some elements
<NavLink className="link header_row_link" to={{ pathname: '/signIn', state: this.setLogInTrue }}> //<-- i thought this would work and give the function in the location of SignIn components state but it does not.
Sign In
</NavLink>
}
}
SignIn.tsx
export class SignIn extends React.Component<RouteComponentProps<{}>, {}> {
constructor() {
super();
}
public render() {
return <div className="signin_wrapper">
<SignInContent />
</div>;
}
}
我想在这里访问该函数并将其传递给SignInContent组件,然后从那里调用该函数。
此代码不会给我任何编译时错误,但每当我点击登录链接时,它会给我以下错误
未捕获的DOMException:无法执行&#39; pushState&#39; on&#39;历史&#39;:函数(){[本机代码]}无法克隆。
我尝试了this解决方案,但它对我不起作用。它仍然给我这个错误或给状态为undefined。我很反应,任何帮助都会受到赞赏
答案 0 :(得分:1)
当通过window.history.state
或{{1}分配给history.replaceState
的状态对象中使用DOM元素或不可序列化的任何内容时,会发生此错误,如@Andreas在评论中所述}。例如,尝试:history.pushState
或改用history.pushState({node: document.body}, 'title', '#/error')
,它将产生类似的{node: History}
错误。要解决此问题,只需删除有问题的对象,或者以某种方式更仔细地考虑将什么内容推入状态。
答案 1 :(得分:1)
我在推送包含函数的 React 组件状态时也遇到了同样的问题。我不想调用 JSON.strinfigy
因为它可以包含日期并且那些不能很好地字符串化/解析。相反,我选择这样做:
window.history.pushState(cleanStateForHistory(state), "", someURL);
/**
* Remove the functions from the state. They can't been pushed into the history.
*/
export function cleanStateForHistory(state) {
const stateWithNoFunctions = {};
for (const key of Object.keys(state)) {
if (typeof key !== "function") {
stateWithNoFunctions[key] = state[key];
}
}
return stateWithNoFunctions;
}
答案 2 :(得分:0)
当React组件状态包含未序列化的对象时,我遇到了同样的问题。
我只需要对整个React状态对象进行字符串化处理,然后将其推入浏览器的历史状态,如下所示:
window.history.pushState(JSON.stringify(state), "", getSecuredURL(url));