分享
三行代码  ›  专栏  ›  技术社区  ›  Tiger_Stripes

当数组映射用于创建html时,子组件不会立即重新呈现

  •  -2
  • Tiger_Stripes  · 技术社区  · 6 天前

    我正在制作我的第一个应用程序。作为一个初学者,我很可能会因为我的代码而被谋杀,但这是事实。

    我试着制作一个视频来展示这种奇怪的行为。似乎只有当子组件映射一个值数组以呈现所需的输出时才会发生这种情况

    https://youtu.be/ysFdCiWr51E

    在代码方面

    子组件由两层组成:

    import React, { useState, useEffect } from 'react';
    import { ReactComponent as FilterIcon } from '../icons/filter.svg';
    import FilterColumnSelector from './filterSelector.js';
    
    export default function FilterDropZone({
      filters,
      removeFilter,
      handleDraggedItem,
      namespace,
      handleAddFilter
    }) {
      const handleDragOver = (event) => {
        event.preventDefault();
        event.stopPropagation();
      };
    
      useEffect(() => {
        console.log(filters);
      }, [filters]);
    
      const handleDrop = (event) => {
        event.preventDefault();
        event.stopPropagation();
        var columnName = event.dataTransfer.getData('text');
    
        console.log(columnName);
        if (columnName) {
          handleAddFilter(columnName);
    
          event.dataTransfer.clearData();
        }
      };
    
      return (
        <div className="filterDropZone">
          <div className="filterIconWrapper">
            <FilterIcon className="filterIcon" />
          </div>
          <div
            className="filterDropZoneInnerDiv"
            onDragOver={(e) => handleDragOver(e)}
            onDrop={(e) => handleDrop(e)}
          >
            <ul>
              {filters.map((filterItem, index, column, type, choices, selectedValues) => (
                <FilterColumnSelector
                  key={index}
                  index={index}
                  column={column}
                  namespace={namespace}
                  type={type}
                  choices={choices}
                  selectedValues={selectedValues}
                  handleDraggedItem={handleDraggedItem}
                  {...filterItem}
                />
              ))}
            </ul>
          </div>
        </div>
      );
    }
    

    下层子层:

    import React, { useState, useEffect } from 'react';
    
    export default function FilterColumnSelector({
      selectedColumn,
      handleDraggedItem,
      namespace,
      index,
      column,
      type,
      choices,
      selectedValues,
      //handleDraggedItem,
      ...rest
    }) {
      const handleDragStart = (event, column) => {
        event.dataTransfer.setData('text', selectedColumn);
        // handleDraggedItem(event.target.id);
      };
    
      return (
        <>
          <li key={index} className="draggableColumnList">
            <div
              id={namespace.concat(column)}
              className="draggableColumn"
              draggable="true"
              onDragStart={(event) => handleDragStart(event, column)}
            >
              {column}
            </div>
          </li>
        </>
      );
    }
    
    

    父组件: //JavaScript源代码

    import React, { useState, useEffect } from 'react';
    import './dataExplorer.css';
    import AxisDropZone from './axisDraggableArea.js';
    import FilterDropZone from './filter/filterDropZone.js';
    import DraggableColumnList from './ColumnList/draggableColumnList.js';
    import SearchBar from './search/search.js';
    import ColourDropZone from './colour/colourDropZone.js';
    import SizeDropZone from './size/size.js';
    
    const removeItemFromArray = (item, array) => {
      var index = array.indexOf(item);
      if (index !== -1) {
        array.splice(index, 1);
      }
      return array;
    };
    
    const uniqueValues = (data, column) => {
      var unique = [];
      var distinct = [];
      for (let i = 0; i < data.length; i++) {
        if (!unique[data[i][column]]) {
          distinct.push(data[i][column]);
          unique[data[i][column]] = 1;
        }
      }
      return distinct;
    };
    
    export default function DataExplorer({ data, filename }) {
      const [columns, setColumns] = useState([]);
      const [childToRemove, setChildToRemove] = useState();
      const [draggedItem, setDraggedItem] = useState();
      const [xaxisColumn, setXaxisColumn] = useState();
      const [yaxisColumn, setYaxisColumn] = useState();
      const [xaxisModification, setXaxisModification] = useState('');
      const [yaxisModification, setYaxisModification] = useState('');
      const [searchTerm, setSearchTerm] = useState();
      const [colourColumn, setColourColumn] = useState();
      const [sizeColumn, setSizeColumn] = useState();
      const [filters, setFilters] = useState([]);
    
      useEffect(() => {
        if (data) {
          if (data.length > 0) {
            setColumns(Object.keys(data[0]));
          }
        }
      }, [data]);
    
      const handleDraggedItem = (childId) => {
        setDraggedItem(childId);
      };
    
      const handleXaxisColumn = (newColumn) => {
        setXaxisColumn(newColumn);
      };
      const handleYaxisColumn = (newColumn) => {
        setYaxisColumn(newColumn);
      };
    
      const handleColourColumn = (newColumn) => {
        setColourColumn(newColumn);
      };
    
      const handleSizeColumn = (newColumn) => {
        setSizeColumn(newColumn);
      };
    
      const handleYaxisModification = (newModification) => {
        if (newModification === 'None') {
          setYaxisModification();
        } else {
          setYaxisModification(newModification);
        }
      };
      const handleXaxisModification = (newModification) => {
        setXaxisModification(newModification);
      };
    
      const handleSearchChange = (newTerm) => {
        setSearchTerm(newTerm);
      };
    
      const handleRemoveFilter = (columnToRemove) => {
        if (columnToRemove) {
        }
      };
    
      const handleAddFilter = (columnName) => {
        let newFilters = filters;
    
        let newFilter = {
          column: columnName,
          type: '',
          choices: ['A', 'B'],
          selectedValues: ['A', 'B']
        };
        if (
          !newFilters.some(function (o) {
            return o['column'] === columnName;
          })
        ) {
          newFilters.push(newFilter);
    
          setFilters(newFilters);
          console.log(filters);
        }
      };
    
      return (
        <div className="data-explorer-container">
          <div className="Data">
            <div className="navigation-container">
              <div className="Navigation"></div>
              <div className="Search-Filter">
                <SearchBar onChange={handleSearchChange} />
              </div>
              <div className="Draggable-Columns">
                <DraggableColumnList
                  columns={columns}
                  handleDraggedItem={handleDraggedItem}
                  searchTerm={searchTerm}
                />
              </div>
              <div className="Colours">
                <ColourDropZone
                  draggedItem={draggedItem}
                  handleColourColumn={handleColourColumn}
                  selectedColumn={colourColumn}
                  handleDraggedItem={handleDraggedItem}
                  namespace="colour"
                />
              </div>
              <div className="Size">
                <SizeDropZone
                  draggedItem={draggedItem}
                  handleSizeColumn={handleSizeColumn}
                  selectedColumn={sizeColumn}
                  handleDraggedItem={handleDraggedItem}
                  namespace="size"
                />
              </div>
              <div className="Shapes"></div>
            </div>
          </div>
          <div className="Graph-Area">
            <div className="Axis-graph-wrapper">
              <div className="Axis-areas">
                <div className="axis-filter-wrapper">
                  <div className="FilterZone">
                    <FilterDropZone
                      filters={filters}
                      handleAddFilter={handleAddFilter}
                      removeFilter={handleRemoveFilter}
                      handleDraggedItem={handleDraggedItem}
                      namespace="filter"
                    />
                  </div>
                  <div className="AxisZone">
                    <div className="axis-wrapper">
                      <div className="XaxisZone">
                        <AxisDropZone
                          handleDraggedItem={handleDraggedItem}
                          draggedItem={draggedItem}
                          selectedColumn={xaxisColumn}
                          handleColumn={handleXaxisColumn}
                          modifications={false}
                          namespace="xaxis"
                          handleModification={handleXaxisModification}
                          axisModification={xaxisModification}
                          axisLabel="x-axis"
                        />
                      </div>
                      <div className="YaxisZone">
                        <AxisDropZone
                          handleDraggedItem={handleDraggedItem}
                          draggedItem={draggedItem}
                          selectedColumn={yaxisColumn}
                          handleColumn={handleYaxisColumn}
                          modifications={true}
                          namespace="yaxis"
                          handleModification={handleYaxisModification}
                          axisModification={yaxisModification}
                          axisLabel="y-axis"
                        />
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <div className="Graphing-area">
                <div className="graph-container">
                  <div className="Yaxis-Label"></div>
                  <div className="Graph-Title"></div>
                  <div className="Xaxis-Label"></div>
                  <div className="Graph"></div>
                </div>
              </div>
            </div>
          </div>
        </div>
      );
    }
    
    1 回复  |  直到 6 天前
        1
  •  1
  •   Adam    6 天前

    1. 提升状态上升
    2. 不要改变状态。

      const handleAddFilter = (columnName) => {
        // this doesn't do anything, newFilters === filters
        let newFilters = filters; 
    
        let newFilter = {
          column: columnName,
          type: '',
          choices: ['A', 'B'],
          selectedValues: ['A', 'B']
        };
        if (
          !newFilters.some(function (o) {
            return o['column'] === columnName;
          })
        ) {
          // now on this line you are MUTATING state. DON'T MUTATE STATE
          newFilters.push(newFilter);
    
          // newFilters === filters, so you aren't actually updating the state here, but you have mutated it
          setFilters(newFilters);
          console.log(filters);
        }
      };
    

      const handleAddFilter = (columnName) => {
        // filter already added, ignore
        if(filters.some(({column}) => column === columnName)) return;
    
        // add the new filter
        let newFilter = {
          column: columnName,
          type: '',
          choices: ['A', 'B'],
          selectedValues: ['A', 'B']
        };
        setFilters([...filters,newFilter]);
      };