Unbound Record Field Id Error

Unbound Record Field Id Error

I am trying out Reason-React. I am facing a problem when I try to add a key to one of the components.

I have a TodoApp that takes a list of TodoItem as state. The app works fine when I don't have a key for the TodoItem. When I add it, however I am getting a compilation error. I am adding the files here for reference:

TodoItem.re:

type item = {
  id: int,
  title: string,
  completed: bool
};

let lastId = ref(0);

let newItem = () => {
  lastId := lastId^ + 1;
  {id: lastId^, title: "Click a button", completed: false}
};

let toString = ReasonReact.stringToElement;

let component = ReasonReact.statelessComponent("TodoItem");

let make = (~item, children) => {
  ...component,
  render: (self) =>
    <div className="item">
      <input _type="checkbox" checked=(Js.Boolean.to_js_boolean(item.completed)) />
      (toString(item.title))
    </div>
};

TodoApp.re:

let toString = ReasonReact.stringToElement;

type state = {items: list(TodoItem.item)};

type action =
  | AddItem;

let component = ReasonReact.reducerComponent("TodoApp");

let currentItems = [TodoItem.{id: 0, title: "ToDo", completed: false}];

let make = (children) => {
  ...component,
  initialState: () => {items: currentItems},
  reducer: (action, {items}) =>
    switch action {
    | AddItem => ReasonReact.Update({items: [TodoItem.newItem(), ...items]})
    },
  render: ({state: {items}, reduce}) => {
    let numOfItems = List.length(items);
    <div className="app">
      <div className="title">
        (toString("What to do"))
        <button onClick=(reduce((_evt) => AddItem))> (toString("Add Something")) </button>
      </div>
      <div className="items">
        (
          ReasonReact.arrayToElement(
            Array.of_list(
              (List.map((item) => <TodoItem key=(string_of_int(item.id)) item />, items))
              /*List.map((item) => <TodoItem item />, items) This works but the above line of code with the key does not*/
            )
          )
        )
      </div>
      <div className="footer"> (toString(string_of_int(numOfItems) ++ " items")) </div>
    </div>
  }
};

I've added a comment near the line where the error occurs.

The error reads as Unbound record field id, but I am not able to figure out how it is not bound. What am I missing here?

0

1 Answer

Type inference is unfortunately a bit limited when it comes to inferring the type of a record from another module based on the usage of record fields, so you need to give it some help. Two options that should work are:

Annotating the type of ìtem:

List.map((item: TodoItem.item) => <TodoItem key=(string_of_int(item.id)) item />)

or locally opening the module where the record field is used:

List.map((item) => <TodoItem key=(string_of_int(item.TodoItem.id)) item />)
4

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Chloe Bennett
Author

Chloe Bennett

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.