typescript complains the prop { todos }
, it says "Binding element 'todos' implicitly has an 'any' type."
Anyone could help me? I tried so many way still couldn't solve it.. Do I need to also pass the interface to the child?
//TodoList.tsx
import React from "react";
export default function TodoList({ todos }) {
return <div>{todos.id}</div>;
}
//App.tsx
import { useState, useRef } from "react";
import { uuid } from "uuidv4";
import TodoList from "./TodoList";
export default function App() {
interface Todo {
id: string;
title: string | undefined;
completed: boolean;
}
const [todos, setTodos] = useState<Todo[]>([]);
const refTitle = useRef<HTMLInputElement | null>(null);
const handleAdd = () => {
const title = refTitle.current?.value;
setTodos((todos) => {
return [...todos, { id: uuid(), title: title, completed: false }];
});
};
return (
<>
<TodoList todos={todos} />
<input ref={refTitle} type="text" />
<button onClick={handleAdd}>Add</button>
</>
);
}
CodePudding user response:
You should pass the todos
as props
of the Todo
type array.
App.tsx
import { useState, useRef } from "react";
import uuid from "react-uuid";
import TodoList from "./TodoList";
import { Todo } from "./types";
export default function App() {
const [todos, setTodos] = useState<Todo[]>([]);
const refTitle = useRef<HTMLInputElement | null>(null);
const handleAdd = () => {
const title = refTitle.current?.value;
setTodos((prev) => [
...prev,
{ id: uuid(), title: title, completed: false }
]);
};
return (
<>
<TodoList todos={todos} />
<input ref={refTitle} type="text" />
<button onClick={handleAdd}>Add</button>
</>
);
}
TodoList.tsx
import { Todo } from "./types";
export default function TodoList({ todos }: { todos: Todo[] }) {
return (
<>
{todos.map((todo, i) => (
<div key={i}>{todo.title}</div>
))}
</>
);
}
types.ts
export interface Todo {
id: string;
title: string | undefined;
completed: boolean;
}
This is a result of React components only taking objects
as arguments
Here's the working solution https://codesandbox.io/s/props-to-child-tsx-vuzo2s
CodePudding user response:
You have not defined the type of prop that you are passing onto the Todolist. Just add your interface from app.tsx to todolist.tsx and there pass the type Todo to props.I have edited the same in the code snippets below.
import React from "react";
import {Todo} from "./App"
export default function TodoList({ todos : Todo }) {
return <div>{todos.id}</div>;
}
import { useState, useRef } from "react";
import { uuid } from "uuidv4";
import TodoList from "./TodoList";
export interface Todo {
id: string;
title: string | undefined;
completed: boolean;
}
export default function App() {
const [todos, setTodos] = useState<Todo[]>([]);
const refTitle = useRef<HTMLInputElement | null>(null);
const handleAdd = () => {
const title = refTitle.current?.value;
setTodos((todos) => {
return [...todos, { id: uuid(), title: title, completed: false }];
});
};
return (
<>
<TodoList todos={todos} />
<input ref={refTitle} type="text" />
<button onClick={handleAdd}>Add</button>
</>
);
}