React:为什么页面刷新时 state 或 props 为 null?

2024-01-28

我在页面的左框架上显示树视图。树是从 xml 文件生成的。单击每个节点时,组件将在页面的右侧框架中打开。 ProductsTreeView 是树组件,Add_Category 是单击树节点之一时将打开的组件。我通过路由传递道具。只要页面不刷新,一切都工作正常。在页面刷新的情况下,道具在 Add_Category 页面中显示为 null。请帮助如何解决这个问题。 [1]:https://i.stack.imgur.com/QeYB6.gif https://i.stack.imgur.com/QeYB6.gif

App.js

import React, { Component } from 'react';
import { Switch, Route, BrowserRouter, Redirect } from "react-router-dom";
import Home from './components/Home';

 export class App extends Component {
    render() {
        return (
            <div>
                <BrowserRouter>
                    <Switch>
                        <Route path="/" component={Home} />
                        <Redirect to="/" />
                    </Switch>
                </BrowserRouter>
             </div>
        );
    }
}
export default App;
_____________
 
Home.js

import React from 'react';
import { Route} from "react-router-dom";
import ProductsTree from '.ProductsTreeView';
import AddCategory from './Add_Category';

class Home extends React.Component 
    constructor(props) {
        super(props);
        this.state =
        {
            currentNode: {},
            data: "",
        };
        this.setCurrentNode = this.setCurrentNode.bind(this);
    }

    setCurrentNode(node) {
        this.setState({ currentNode: node });
    }

    render() {
        return (
            <div>
<table className="Container">

<tbody><tr width="100%">

<td className="TreeContainer">

   <ProductsTree setCurrentNode={this.setCurrentNode} /> </td>

<td className="BodyContainer">

                                             <Route path="/Add_Category">

                                                    <AddCategory key_id={this.state.currentNode.key_id} />

                                                </Route>

                            </td>   </tr>        </tbody>    </table>

            </div>

        );

    }

}

export default Home;
_________________________

***Add_Category***
 
import React from 'react'

export class Add_Category extends React.Component {

       constructor(props) {

             super(props);

             this.state = {

                    ID: "",

                    Name: "",

             };

       }

       componentDidMount() {
         if (typeof this.props.key_id !== 'undefined') {
             const ID= this.props.key_id;
             this.getName(ID);
          }
       }

       componentDidUpdate(prevProps) {

             if (prevProps.key_id !== this.props.key_id) {

                    console.log(`key_id: ${this.props.key_id}`);
                    const ID= this.props.key_id;
                    this.getName(ID);

             }

       }
       async getName(ID) {
                   await fetch(REQUEST_URL)
                           .then(response => response.json())
                           .then((data) => {
                                 this.setState({
                                       Name: data,
                                      ID: this.props.key_id,
                                        loading: false})
                                 console.log(this.state.Name)
                           })[![enter image description here][1]][1]             
       }
      render() {
        return (
                    <div>
                          <form>
       {this.state.Name}

                                </form>

                           </div>

 

        );

    }

}

export default Add_Category;

_________________________
ProductsTreeView.js
import React, { Component } from 'react';

import ReactHtmlParser from 'react-html-parser';

import axios from 'axios';

import XMLParser from 'react-xml-parser';

import { Link } from "react-router-dom";

 

class ProductsTreeView extends Component {

    render() {

        return (

            <div id="TreeView">

                <TreeView setCurrentNode={this.props.setCurrentNode} />

            </div>

        );

    }

}

 

class Node {

    description = 'n/a';

    id = -1;

    key_id = -1;

    linkpagename = '';

    isActive = false;

    nodes = [];

 

    constructor(description, id, key_id, linkpagename) {

        this.description = description;

        this.id = id;

        this.key_id = key_id;

        this.linkpagename = linkpagename;

    }

 

    static nodesFromXml(xml) {

        const map = (entity, nodes) => {

            const id = entity.attributes['id'];

            const key_id = entity.attributes['key-id'];

            const descriptionText =

                entity.children[

                    entity.children.findIndex((child) => child.name === 'description')

                ].value;

            const entities = entity.children.filter(

                (child) => child.name === 'entity'

            );

            var linkPageName = entity.attributes['link-page-name'];

            linkPageName = linkPageName.replace(".aspx", "");

            const node = new Node(descriptionText, id, key_id, linkPageName);

            nodes.push(node);

            entities.forEach((entity) => map(entity, node.nodes));

        };

 

        const parsedData = new XMLParser().parseFromString(xml);

 

        const entities = parsedData.children.filter(

            (child) => child.name === 'entity'

        );

 

        const nodes = [];

        entities.forEach((entity) => map(entity, nodes));

        return nodes;

    }

}

 

class TreeView extends React.Component {

    constructor(props) {

        super(props);

        this.state = { nodes: [] };

        this.toggleNode = this.toggleNode.bind(this);

    }

 

    componentDidMount() {

        axios

            .get(REQUEST_URL, { 'Content-Type': 'application/xml; charset=utf-8' })

            .then((response) =>

                this.setState({ nodes: Node.nodesFromXml(response.data) }))

                    .catch(function (error) {

                        if (error.response) {

                            // Request made and server responded

                            console.log(error.response.data);

                            console.log(error.response.status);

                            console.log(error.response.headers);

                        } else if (error.request) {

                            // The request was made but no response was received

                            console.log(error.request);

                        } else {

                            // Something happened in setting up the request that triggered an Error

                            console.log('Error', error.message);

                        }

 

                    });

    }

 

    render() {

        const nodes = this.state.nodes;

 

        return (

            <ul>

                 {nodes.map((node) => (

                    <TreeNode

                        id={node.id}

                        key={node.key_id}

                        node={node}

                        onToggle={this.toggleNode}

                        setCurrentNode={this.props.setCurrentNode}

                    />

                ))}

            </ul>

        );

    }

 

    toggleNode(node) {

        this.props.setCurrentNode(node);

 

        function _toggleNode(currentNode, node) {

            if (currentNode.id === node.id) { //currentNode.id === node.id)

                {

                    if (currentNode.key_id === node.key_id)

                    {

                        currentNode.isActive = !currentNode.isActive;

                    }

                }

            }

            else

            {

                currentNode.nodes.forEach((childNode) => _toggleNode(childNode, node));

            }

        }

 

        const nodes = this.state.nodes;

        nodes.forEach((currentNode) => _toggleNode(currentNode, node));

        this.setState((state) => (state.nodes = nodes));

    }

}

 

class TreeNode extends React.Component {

    render() {

        const node = this.props.node;

        const onToggle = this.props.onToggle;

        let activeChildren = null;

        if (node.isActive && node.nodes.length > 0) {

            activeChildren = (

                <ul>

                    {node.nodes.map((node) => (

                        <TreeNode

                            id={node.id}

                            key={node.key_id}

                            node={node}

                            onToggle={onToggle}

                        />

                    ))}

                </ul>

            );

        }

 

        return (

                <li

                id={node.id} linkpagename={node.linkpagename}

                key={node.key_id}

                onClick={(event) => {

                    event.stopPropagation();

                    onToggle(node);                 

                }}

            >

                <Link to={node.linkpagename} style={{ textDecoration: 'none', color: '#000000' }} >

{node.description}</Link>

             {activeChildren}

                </li>

           

        );

    }

}

export default ProductsTreeView;

thanks


React 状态是短暂的,它存在于内存中。当页面重新加载时,应用程序也会重新加载。状态中的任何内容都会被重置。

这似乎是需要将 React 状态持久保存到长期存储的情况,以便在重新加载页面时可以重新初始化状态。

这是一个例子:

const initialState = {
  currentNode: {},
  data: "",
};

class Home extends React.Component 
  constructor(props) {
    super(props);
    this.state = initialState;
    this.setCurrentNode = this.setCurrentNode.bind(this);
  }

  componentDidMount() {
    // initialize from storage
    this.setState(JSON.parse(localStorage.getItem("homeState")) ?? initialState);
  }

  componentDidUpdate() {
    // persist updates to storage
    localStorage.setItem("homeState", JSON.stringify(this.state));
  }

  setCurrentNode(node) {
    this.setState({ currentNode: node });
  }

  render() {
    return (
      <div>
        <table className="Container">
          <tbody>
            <tr width="100%">
              <td className="TreeContainer">
                <ProductsTree setCurrentNode={this.setCurrentNode} />
              </td>
              <td className="BodyContainer">
                <Route path="/Add_Category">
                  <AddCategory key_id={this.state.currentNode.key_id} />
                </Route>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    );
  }
}

如果其他组件的状态需要通过页面重新加载来保留,它们也需要这样做。

添加类别

const initialState = {
  ID: "",
  Name: "",
}

const getStorageKey = (id) => `addCategory-${id}`;

export class AddCategory extends React.Component {
  constructor(props) {
    super(props);

    this.state = initialState;
  }

  componentDidMount() {
    const { key_id } = this.props;

    // initialize from storage
    this.setState(
      JSON.parse(localStorage.getItem(getStorageKey(key_id))) ?? initialState
    );

    if (typeof key_id !== 'undefined') {
      this.getName(key_id);
    }
  }

  componentDidUpdate(prevProps, prevState) {
    const { ID } = this.state;
    const { key_id } = this.props;

    if (prevProps.key_id !== key_id) {
      console.log(`key_id: ${key_id}`);
      this.getName(key_id);
    }

    if (prevState.ID !== ID) {
      // persist updates to storage
      localStorage.setItem(getStorageKey(ID), JSON.stringify(this.state));
    }
  }

  async getName(ID) {
    const response await fetch(REQUEST_URL);
    const data = await response.json();
    this.setState({
      Name: data,
      ID,
      loading: false
    });
  }

  render() {
    ...
  }
}

TreeView

class TreeView extends React.Component {
  constructor(props) {
    super(props);
    this.state = { nodes: [] };

    this.toggleNode = this.toggleNode.bind(this);
  }

  componentDidMount() {
    // initialize from storage
    const storedState = JSON.parse(localStorage.getItem("treeview"));

    if (storedState) {
      this.setState(storedState);
    } else {
      axios.get(REQUEST_URL, { 'Content-Type': 'application/xml; charset=utf-8' })
        .then((response) => {
          this.setState(
            { nodes: Node.nodesFromXml(response.data) },
           () => {
              // persist updated state to storage
              localStorage.setItem("treeview", JSON.stringify(this.state));
            }
          );
        })
        .catch(function (error) {
          ...
        });
    }
  }

  ...
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React:为什么页面刷新时 state 或 props 为 null? 的相关文章

随机推荐