页面切换如何禁止刷新呢?

两个页面切换,如何禁止刷新呢?不借助浏览器缓存方法,比如localStorage、sessionStorage,
切换会重新刷新页面,想要的结果是第一次切换刷新后,再次切换到当前页面无需刷新,就跟antd的Tabs一样效果

比如下面两个页面,用Radio来互相切换,比如第一个ChildComponents_1页面input输入“测试”内容,切换到ChildComponents_2,再切换ChildComponents_1,发现input输入“测试”内容已经没了,页面被重新初始化了,这个不通过浏览器缓存方法该怎么解决呢?

import React from 'react';
import {Radio,Input} from 'antd';
import ChildComponents_2 from './ChildComponents_2';

class ChildComponents_1 extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            inputValue:'',
            radioValue:'组件一'
        }
    }
    render() {
        const {inputValue,radioValue} = this.state;
        return (
            <>
                {
                    radioValue==='组件一'?(
                        <div>
                            <Input
                                value={inputValue}
                                onChange={(e)=>{
                                    this.setState({inputValue:e.target.value});
                                }}
                            />
                            <Radio.Group
                                onChange={(e)=>{
                                    this.setState({radioValue:e.target.value});
                                }}
                            >
                                <Radio.Button value="组件一">组件一</Radio.Button>
                                <Radio.Button value="组件二">组件二</Radio.Button>
                            </Radio.Group>
                        </div>
                    ):(
                        <ChildComponents_2 />
                    )
                }
            </>
        );
    }
}
export default ChildComponents_1;


import React from 'react';
import {Radio,Input} from 'antd';
import ChildComponents_1 from './ChildComponents_1';

class ChildComponents_2 extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            inputValue:'',
            radioValue:'组件二'
        }
    }
    render() {
        const {inputValue,radioValue} = this.state;
        return (
            <>
                {
                    radioValue==='组件二'?(
                        <div>
                            <Input
                                value={inputValue}
                                onChange={(e)=>{
                                    this.setState({inputValue:e.target.value});
                                }}
                            />
                            <Radio.Group
                                onChange={(e)=>{
                                    this.setState({radioValue:e.target.value});
                                }}
                            >
                                <Radio.Button value="组件一">组件一</Radio.Button>
                                <Radio.Button value="组件二">组件二</Radio.Button>
                            </Radio.Group>
                        </div>
                    ):(
                        <ChildComponents_1 />
                    )
                }
            </>
        );
    }
}
export default ChildComponents_2;
阅读 1.2k
avatarAI BotBETA

你可以使用React的useStateuseEffect钩子来达到这个效果。首先,在切换到新的页面时,保存当前页面的状态。然后在回到这个页面时,从保存的状态中恢复状态。

下面是使用React的hooks实现这个功能的一种方式:

import React, { useState, useEffect } from 'react';
import { Radio, Input } from 'antd';

const ChildComponents_1 = () => {
  const [inputValue, setInputValue] = useState('');
  const [radioValue, setRadioValue] = useState('组件一');
  const [isVisited, setIsVisited] = useState(false);

  useEffect(() => {
    if (radioValue === '组件一' && !isVisited) {
      setIsVisited(true);
    }
  }, [radioValue]);

  return (
    <div>
      <Input value={inputValue} onChange={(e) => setInputValue(e.target.value)} />
      <Radio.Group onChange={(e) => setRadioValue(e.target.value)}>
        <Radio.Button value="组件一">组件一</Radio.Button>
        <Radio.Button value="组件二">组件二</Radio.Button>
      </Radio.Group>
    </div>
  );
};

const ChildComponents_2 = () => {
  const [inputValue, setInputValue] = useState('');
  const [radioValue, setRadioValue] = useState('组件二');
  const [isVisited, setIsVisited] = useState(false);

  useEffect(() => {
    if (radioValue === '组件二' && !isVisited) {
      setIsVisited(true);
    }
  }, [radioValue]);

  return (
    <div>
      <Input value={inputValue} onChange={(e) => setInputValue(e.target.value)} />
      <Radio.Group onChange={(e) => setRadioValue(e.target.value)}>
        <Radio.Button value="组件一">组件一</Radio.Button>
        <Radio.Button value="组件二">组件二</Radio.Button>
      </Radio.Group>
    </div>
  );
};

在这个例子中,我添加了一个新的状态isVisited来跟踪页面是否被访问过。然后,在useEffect钩子中,如果当前页面是第一次被访问,就设置isVisitedtrue。这样,无论何时返回这个页面,都不会重新初始化。

2 个回答

页面没有刷新,只是每次切换的时候都生成了一个新的实体,没有使用旧的

重新组织一下代码,用hook来是实现

// ChildComponet.js
import React from "react";
import { Input } from "antd";
import PropTypes from "prop-types";

function ChildComponent({ show }) {
  const [value, setValue] = React.useState("");
  if (!show) return null;    /* 关键点 */
  return (
    <Input
      value={value}
      onChange={(e) => {
        setValue(e.target.value);
      }}
    />
  );
}
// 用于防止eslint报错
ChildComponent.propTypes = {
  show: PropTypes.bool.isRequired,
};

export default ChildComponent;
// ParentComponet.js
import React from "react";
import { Radio } from "antd";
import ChildComponent from "./ChildComponent";

function ParentComponent() {
  const [value, setValue] = React.useState("组件一");
  return (
    <>
      <div>
        {/*
            这两个实体一开始就是都存在的,只是切换的时候,返回的值不同。但是它们的状态都保存在各自实体里了。
        */}
        <ChildComponent show={value === "组件一"} />
        <ChildComponent show={value === "组件二"} />
        <Radio.Group
          onChange={(e) => {
            setValue(e.target.value);
          }}
        >
          <Radio.Button value="组件一">组件一</Radio.Button>
          <Radio.Button value="组件二">组件二</Radio.Button>
        </Radio.Group>
      </div>
    </>
  );
}

export default ParentComponent;
//App.js
import "./styles.css";
import ParentComponent from "./ParentComponent";
export default function App() {
  return (
    <ParentComponent />
  );
}

codesandbox

不仅仅是能不能保存状态的问题,而且还有性能问题,每切换一次就生成一个实体。一个组件A中生成一个组件B,一个组件B又能生成一个组件A,这个结构就有问题。
image.png

修改:不将Radio.Button拆出来,去掉嵌套调用,状态上移

// ChildComponent.js
import React from "react";
import { Input, Radio } from "antd";
import PropTypes from "prop-types";

function ChildComponent({ show, changeTab }) {
  const [value, setValue] = React.useState("");
  if (!show) return null; /* 关键点 */
  return (
    <div>
      <Input
        value={value}
        onChange={(e) => {
          setValue(e.target.value);
        }}
      />
      <Radio.Group
        onChange={(e) => {
          changeTab(e.target.value);
        }}
      >
        <Radio.Button value="组件一">组件一</Radio.Button>
        <Radio.Button value="组件二">组件二</Radio.Button>
      </Radio.Group>
    </div>
  );
}
// 用于防止eslint报错
ChildComponent.propTypes = {
  show: PropTypes.bool.isRequired,
};

export default ChildComponent;
// ParentComponent.js
import React from "react";
import { Radio } from "antd";
import ChildComponent from "./ChildComponent";

function ParentComponent() {
  const [value, setValue] = React.useState("组件一");
  return (
    <>
      <div>
        <ChildComponent show={value === "组件一"} changeTab={setValue} />
        <ChildComponent show={value === "组件二"} changeTab={setValue} />
      </div>
    </>
  );
}

export default ParentComponent;
//App.js
import "./styles.css";
import ParentComponent from "./ParentComponent";
export default function App() {
  return <ParentComponent />;
}

最简单的就是不使用三元运算符 还是直接通过css去控制。

推荐问题
logo
Microsoft
子站问答
访问
宣传栏