Recoil: Unable to fix recutsive call of set State

Created on 8 Jun 2020  路  3Comments  路  Source: facebookexperimental/Recoil

Hello, I'm having problems with a setState in a recursive call but I honestly can't find it in my code. So 2 thing: first is there a debugging software akin to helm debugger (should be possible since everything is pure in recoil), second can someone help me whit my recursive problems.

========== helper function

export default function log(value)
{
    console.log(value);
    return (value);
}

export default function compose()
{
    switch (arguments.length)
    {
        case 0:
        return undefined;
        case 1:
        return _.head(arguments)[0];
        default:
        return compose2(_.head(arguments), compose(_.tail(arguments)));
    }
}

const compose2 = (f, g) => function ()
{
    return (f(g.apply(null, arguments)));
}

========== incriminated File
import _ from "lodash";
import { atom, selector, useRecoilState } from "recoil";
import DatePicker from 'react-date-picker';

const lowerDate = atom({
    key: "lowerDate",
    default: null
});

const upperDate = atom({
    key: "upperDate",
    default: null
});

export const getHiddenReports = atom({
    key: "getHiddenReports",
    default: []
});

const reportNumber = atom({
    key: "reportNumber",
    default: 5
});

export const getReportsIDs = selector({
    key: "getReportsIDs",
    get: ({get}) => {
        const hiddenRepports = get(getHiddenReports);
        const numberOfReports = get(reportNumber);

        return (_
                .chain(hiddenRepports)
                .take(numberOfReports)
                .map((report) => report.reportID)
                .value()
               );
    }
});

export const getReports = selector({
    key: "getReports",
    get: ({get}) => {
        const ids = get(getReportsIDs);
        const reports = get(getHiddenReports);

        return (_
                .chain(ids)
                .map((id) => _.find(reports, ["reportID", id]))
                .value()
               );
    }
});

const defaultGetter = {
    head: _.head,
    last: _.last
}

const defaultDate = _.memoize((getDefaultKey) =>  selector({
    key: "calcutaltedDate",
    get: ({get}) => {
        const reports =  get(getReports);
        const report = defaultGetter[getDefaultKey](reports);
        const date = new Date();
        const [month, day, year] = _.chain(report.startreport)
              .split("/")
              .map((e) => parseInt(e))
              .value();

        return (date.setFullYear(year, month, day));
    }
}));

const calcutaltedDate = _.memoize((defaultHookKey, currentDate) =>  selector({
    key: "calcutaltedDate",
    get: ({get}) => {
        const defaultDateV = log(compose(
            get,
            defaultDate)(defaultHookKey));
        return (currentDate ? currentDate : defaultDateV);
    }
}));

const applyDatePicker = (hook, defaultGetterKey) => () => {
    console.log("Hi am i recusive");
    const [currentDate, currentSetter] = useRecoilState(hook);
    const [calculatedValue] =
          useRecoilState(
              calcutaltedDate(defaultGetterKey, currentDate));
    return (
        <DatePicker
            calendarIcon = { null }
            clearIcon = { null }
            onChange = { currentSetter }
            value = { calculatedValue }
        />
    );
}

const LowerDatePicker = applyDatePicker(lowerDate, "head");
const UpperDatePicker = applyDatePicker(upperDate, "last");

the problem occurs when I render Lower/UpperDatePicker.
I really don't see recursion anywhere.

I should add that changing


const calcutaltedDate = _.memoize((defaultHookKey, currentDate) =>  selector({
    key: "calcutaltedDate",
    get: ({get}) => {
        const defaultDateV = log(compose(
            get,
            defaultDate)(defaultHookKey));
        return (currentDate ? currentDate : defaultDateV);
    }
}));

======= to 

const calcutaltedDate = _.memoize((defaultHookKey, currentDate) =>  selector({
    key: "calcutaltedDate",
    get: ({get}) => {
        // const defaultDateV = log(compose(
        //    get,
        //    defaultDate)(defaultHookKey));
        return (currentDate ? currentDate : null);
    }
}));

is letting the page render but doing a similar thing(commenting the logic and returning null) to the defaultDate selector does not yield the same result (ie recursive error and a blank page).

thank you for having taken time to read this.

question

Most helpful comment

@julienJean99 - We are working on an API which will allow visualizing the state graph, maintaining a history, and rolling back.

All 3 comments

This part:

const defaultDate = _.memoize((getDefaultKey) =>  selector({
    key: "calcutaltedDate",

is problematic because you are creating a selector with a duplicate ID for each getDefaultKey value. Try using selectorFamily for this pattern.

thank you so much! That fixed it. :)

I had another question about something that would help debugging like maybe helm(state logging and being able to roll back the state tree) or maybe a state visualisation graph?

@julienJean99 - We are working on an API which will allow visualizing the state graph, maintaining a history, and rolling back.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jamiewinder picture jamiewinder  路  3Comments

atanasster picture atanasster  路  3Comments

Sawtaytoes picture Sawtaytoes  路  4Comments

yuantongkang picture yuantongkang  路  3Comments

adrianbw picture adrianbw  路  3Comments