Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
248 views
in Technique[技术] by (71.8m points)

javascript - React component loads data twice on moving back-and-forth between tabs

For some reason my React component seems to remember its old state when going to another tab and back again, instead of reloading completely.

Basically when I click on the "Create" tab in my navbar and back to the "Board" tab data is populated twice instead of once, see image below. When going back the Board component this.state has two of each taskIds, as if it the component state still had the data from the initial page load when loading again. I have a React component looking like this:

enter image description here

const columnOrder = ['todo', 'in-progress', 'in-review', 'done']
const EMPTY_COLUMNS = {
  'todo': {
    id: 'todo',
    title: 'TODO',
    taskIds: []
  },
  'in-progress': {
    id: 'in-progress',
    title: 'In Progress',
    taskIds: [],
  },
  'in-review': {
    id: 'in-review',
    title: 'In Review',
    taskIds: []
  },
  'done': {
    id: 'done',
    title: 'Done',
    taskIds: []
  }
};

export class Board extends Component {
   constructor(props) {
        super(props);
        this.onLoadEpic = this.onLoadEpic.bind(this);
        this.state = {
            columnOrder: columnOrder,
            columns: {
                'in-progress': {
                    id: 'in-progress',
                    title: 'In Progress',
                    taskIds: [],
                },
            // ...more columns similar to above
            },
        };
    
    // Load state data on mount
    componentDidMount() {
        loadEpic(arg1, arg2);
    }

    // Async function loading items from DB and formatting into useful columns
    async loadEpic(arg1, arg2) {
        axios.get(...)
            .then((response) => {
                let data = response.data;
                let newTasks = {};
                let newColumns = EMPTY_COLUMNS;
                
                data.taskItems.forEach(function(item) {
                   let id = item.id.toString();
                   newColumns[item.status]["taskIds"].push(id);
                   newTasks[id] = {
                       ...item,
                       id: id
                   }
                });
                this.setState({
                    tasks: newTasks,
                    columns: newColumns
                });
            })
    }

    render() {
        // Prints ["7"] on initial load and ["7", "7"] after going back and forth
        console.log(this.state.columns["in-progress"].taskIds);
        return (
          // Simplified, but this is the main idea
          <Container>
          <DragDropContext  onDragEnd={this.onDragEnd}>
              {
                  this.state.columnOrder.map((columnId) => {
                      const column = this.state.columns[columnId]
                      const tasks = column.taskIds.map(taskId => this.state.tasks[taskId]
                      return (
                          <Column key={column.id} column={column} tasks={tasks}/>
                      )
                  }
              }
          </DragDropContext>
          </Container>
        )
    }

}

and an App.js with Routing looking like this:

export default class App extends Component {
  static displayName = App.name;

  render () {
    return (
      <Layout>
        <Route exact path='/' component={Board} />
        <Route exact path='/create' component={Create} />
      </Layout>
    );
  }
}
question from:https://stackoverflow.com/questions/65874135/react-component-loads-data-twice-on-moving-back-and-forth-between-tabs

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Okay, so I figured it out: it's the EMPTY_COLUMNS constant that is bugging out. When the component is re-rendered, the same EMPTY_COLUMNS object is referenced - so the constant is being appended to. Instead, I should make a copy of the empty columns:

// Before - same object is being appended to, doesn't work
let newColumns = EMPTY_COLUMNS;
// After - create a deep copy of the constant, does work
let newColumns = JSON.parse(JSON.stringify(EMPTY_COLUMNS));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...