1
votes

I am creating spfx webpart with React framework. I am having render method where all the controls were rendered. i am having a button, few checkboxes in the DOM which will send data to SharePoint using post method this.context.spHttpClient.post when user clicks on button. I am able to submit the data to SharePoint. But once I submit the data I am not able to reload the spfx webpart. I have to reload the web part again without reloading the page. I have tried to call the render method again. Of course it may not be correct way, so it is not working.

2

2 Answers

1
votes

You can either call a force reload or set state as shown here and here

"By default, when your component’s state or props change, your component will re-render. If your render() method depends on some other data, you can tell React that the component needs re-rendering by calling forceUpdate(). Calling forceUpdate() will cause render() to be called on the component, skipping shouldComponentUpdate(). This will trigger the normal lifecycle methods for child components, including the shouldComponentUpdate() method of each child. React will still only update the DOM if the markup changes. Normally you should try to avoid all uses of forceUpdate() and only read from this.props and this.state in render()."

0
votes

You should use this methods:

  1. componentDidMount()
  2. componentDidUpdate(prevProps, prevState, snapshot)
  3. componentWillUnmount()
  4. shouldComponentUpdate(nextProps, nextState)

More info here https://reactjs.org/docs/react-component.html.

For example, in a project i have a list of buttons and i do a click so i send the event to another component that use the state:

LeftPanel.tsx :

import * as React from 'react';
import { Button } from 'react-bootstrap';
import { Event } from '../interfaces/Event';
import '../components/GruposDeColaboracion.module.scss';
import '../css/leftPanel.css';

export class LeftPanel extends React.Component {
    constructor(public props, public context) {
        super(props, context);
    }

    private getAllGroups = (e) => {
        this.clearState();
        this.setActive('allGroups');
        this.props.setEvent(Event.GET_ALL_GROUPS);
        //e.stopPropagation();
    }

    public render():JSX.Element{
            return (
                <div className="list-group">
                    <Button
                        id="allGroups"
                        onClick={this.getAllGroups}
                        className="list-group-item rounded-0 list-group-item-action btn btn-default active">
                        Todos
                    </Button>
                </div>
            );
    }
}

MainPanel.tsx:

import * as React from 'react';
import { LeftPanel } from '../views/LeftPanel';
import { CenterPanel } from '../views/CenterPanel';
import { IHomeState } from '../interfaces/IHomeState';

export class MainPanel extends React.Component<{}, IMainState> {

    constructor(public props, public context) {
        super(props, context);
        this.state = {
            event: null
        };
    }

    private getEvent = (event) => {
        this.setState({ event: event });
    }

    public shouldComponentUpdate(nextProps, nextState): boolean {
        if (this.state.event != nextState.event) {
            return true;
        }
        return false;
    }

    public render(): JSX.Element {
            return (
                <div className="row">
                    <div className="col-md-2" style={{ maxWidth: '250px' }}>
                        <LeftPanel setEvent={this.getEvent} />
                    </div>
                    <div className="col-md-10">
                        <CenterPanel event={this.state.event} context={this.props.context} />
                    </div>
                </div>
            );
        }
}

CenterPanel.tsx :

export class CenterPanel extends React.Component<{}, ICenterPanelState> {
    constructor(public props, public context) {
        super(props, context);
    }

  public componentWillMount() {

        this.state = {
            render: <Spinner />
        };
    }

  public componentWillReceiveProps(nextProps) {
    if (nextProps.event == Event.GET_ALL_GROUPS) {
      let dataForRender = 'Hello';
      this.setState({
        render: <ResponseHandler data = {dataForRender}/>
      });
    }
  }
    public render():JSX.Element{
        return(
        <div>
            {this.state.render}
        </div>
        );
    }
}

ResponseHandler.tsx :

import * as React from 'react';

export class ResponseHandler extends React.Component {

    constructor(public props, public context) {
        super(props, context);
    }

    public render():JSX.Element {

        return (
            <div>
                {this.props.data}
            </div>
        );
    }
}

In this example you can see:

  1. Left panel use this.props.setEvent('custom event') to send the event from MainPanel.
  2. In main panel private getEvent = (event) => {...} recive the event and change the state and in render method i have: . You can see the event={this.state.event} that change the prop event in the class CenterPanel.
  3. In center panel public componentWillReceiveProps(nextProps) {....} recive the event and and use state to render.