React-calendar: Rerender titleDisabled

Created on 17 Jun 2020  ·  4Comments  ·  Source: wojtekmaj/react-calendar

Hi there,

This might be an obvious question but what or how can you trigger the titleDisabled to re-render?

We have dropdown that when changed would update the titleDisabled based on the dates returned by the async call.

<Calendar
    onChange={this.onChange}
    value={this.state.date}
    tileDisabled={this.tileDisabled}
/>
tileDisabled = ({ date }) => {
    var theDate = moment(date);
    if (!moment(theDate).isBefore(moment(), "day")) {
        return this.dateHasTimeSlots(date);
    } else {
        return true;
    }
}
async getAvailableDays() {
    const serviceId = this.props.match.params.serviceId;
    const response = await fetch(url);
    const data = await response.json();
    this.setState({ availableDays: data, loading: false });
}

Thanks!

question

Most helpful comment

React Hooks

Use useMemo to update tileDisabled function when needed & when needed only.

function MyApp() {
  const [availableDates, setAvailableDates] = useState([]);
  const [date, setDate] = useState(null);

  useEffect(() => {
    (async () => {
      const nextAvailableDates = await fetch(…);
      setAvailableDates(nextAvailableDates);
    })();
  }, []);

  const tileDisabled = useCallback(({ date }) => {
    return !availableDates.includes(date);
  }, [availableDates]);

  return (
    <Calendar
      onChange={setDate}
      value={date}
      tileDisabled={tileDisabled}
    />
  );
}

React (legacy)

Redefine the function so that it's _referentially unequal_ after re-render:

class MyApp extends React.Component {
  state = {
    availableDates: [],
    date: null,
  }

  componentDidMount() {
    this.getAvailableDates();
  }

  async getAvailableDates() {
    const availableDates = await fetch(…);

    this.tileDisabled = ({ date }) => {
      return !availableDates.includes(date);
    }

    this.setState({
      availableDates,
    });
  }

  onChange(date) {
    this.setState({
      date,
    });
  }

  render() {
    return (
      <Calendar
        onChange={this.onChange}
        value={this.state.date}
        tileDisabled={this.tileDisabled}
      />
    );
  }
}

Alternatively, you can define the function in class body and re-bind the function instead of re-defining it, so that it's referentially unequal:

  this.tileDisabled = this.tileDisabled.bind(this);

All 4 comments

React Hooks

Use useMemo to update tileDisabled function when needed & when needed only.

function MyApp() {
  const [availableDates, setAvailableDates] = useState([]);
  const [date, setDate] = useState(null);

  useEffect(() => {
    (async () => {
      const nextAvailableDates = await fetch(…);
      setAvailableDates(nextAvailableDates);
    })();
  }, []);

  const tileDisabled = useCallback(({ date }) => {
    return !availableDates.includes(date);
  }, [availableDates]);

  return (
    <Calendar
      onChange={setDate}
      value={date}
      tileDisabled={tileDisabled}
    />
  );
}

React (legacy)

Redefine the function so that it's _referentially unequal_ after re-render:

class MyApp extends React.Component {
  state = {
    availableDates: [],
    date: null,
  }

  componentDidMount() {
    this.getAvailableDates();
  }

  async getAvailableDates() {
    const availableDates = await fetch(…);

    this.tileDisabled = ({ date }) => {
      return !availableDates.includes(date);
    }

    this.setState({
      availableDates,
    });
  }

  onChange(date) {
    this.setState({
      date,
    });
  }

  render() {
    return (
      <Calendar
        onChange={this.onChange}
        value={this.state.date}
        tileDisabled={this.tileDisabled}
      />
    );
  }
}

Alternatively, you can define the function in class body and re-bind the function instead of re-defining it, so that it's referentially unequal:

  this.tileDisabled = this.tileDisabled.bind(this);

@wojtekmaj The React Hooks example doesn't works anymore :(

I copied the exact example, but got a error with the useMemo hook? Does anyone know a fix? 👀

image

Fixed the example, sorry

Thank you for the quick response! 🙏

Was this page helpful?
0 / 5 - 0 ratings

Related issues

akabab picture akabab  ·  4Comments

dumkanki picture dumkanki  ·  4Comments

spoldman picture spoldman  ·  4Comments

mikeyharris89 picture mikeyharris89  ·  4Comments

rmccue picture rmccue  ·  4Comments