1

I'm doing a tutorial on React Hooks and fetching data. Here's my component to fetch customers and map them out in a list:

const useFetch = (url: string) => {
  const [customers, setCustomers] = useState<null | []>(null);
  const [loading, setLoading] = useState(true);

  // Similiar to componentDidMount() and componentDidUpdate()
  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(url);
      setCustomers(result.data);
      setLoading(false);
    };
    fetchData();
  });

  return { customers, loading };
};

const url = 'https://jsonplaceholder.typicode.com/users';

export const LatestCustomers: React.FC<Props> = ({
  description
}: Props): JSX.Element => {
  const { customers, loading } = useFetch(url);

  return (
    <Container>
      {loading ? (
        <div>...Loading...</div>
      ) : (
        <tr>
          {customers.map(customer => (
            <div key="user.id">{customer.name}</div>
          ))}
        </tr>
      )}
    </Container>
  );
};

With that, I got the error:

Object is possibly 'null'.  TS2531

    108 |               ) : (
    109 |                 <tr>
  > 110 |                   {customers.map(customer => (
        |                    ^
    111 |                     <div key="user.id">{customer.name}</div>
    112 |                   ))}
    113 |                 </tr>

How do I solve this?

3
  • maybe const { customers = [], loading } = useFetch(url); will solve Commented Jun 7, 2019 at 11:25
  • There are several solutions to the problem, but basically either: 1. make sure it's never null; or 2. deal with the possibility that it might be null (null.map is a TypeError). Commented Jun 7, 2019 at 11:26
  • 1
    Possible duplicate of TS2531: Object is possibly 'null' Commented Jun 7, 2019 at 11:26

2 Answers 2

1

Because the type supplied to useState is null | [] then customers is given that type signature.

There are a couple of ways to deal with this. My suggestion would be to start with an empty array:

const [customers, setCustomers] = useState<[]>([]);

Alternatively if you wish to maintain the optional typing then you should check customers is not null first:

{customers && customers.map(customer => ( ...

Or if you're really sure it will always be defined you could use the TypeScript non-null assertion ! operator:

{customers!.map(customer => (
Sign up to request clarification or add additional context in comments.

2 Comments

I tried all of them, it gives Property 'name' does not exist on type 'never'.
So the problem in your question is solved but now TS is expecting customer to be typed. Do you have a type defined for your customer objects? If so, use it: const [customers, setCustomers] = useState<Customer[]>([]);
1

A robust solution to handle nullable value could be to use an Option in fp-ts and fromNullable

https://github.com/gcanti/fp-ts/blob/master/src/Option.ts

Example:

{fromNullable(customers).map(x=> {...})}

Interesting article: https://davetayls.me/blog/2018/05/20/fp-ts-01-working-with-nullable-values

Otherwise more straightforward approach:

{customers && customers.map(x => ( ...

2 Comments

But then it gives Property 'name' does not exist on type 'never'.
please post the code you are trying, I would be happy to help! thanks

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.