kibana/examples/routing_example/public/random_number_example.tsx
Anton Dosov 240c4ff15b
[react@18] More breaking type fixes (should be the last pr) (#192266)
## Summary

Part of https://github.com/elastic/kibana/issues/138222

in @types/react@18 types
https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56210. This PR
addresses a bunch of remaining fixes **(hopefully the last mass ping PR
like this)** The most common are:


### 1 Objects are no longer considered a valid ReactNode

In types@17 the ReactNode typing was too soft, it allowed objects and
functions being passed as ReactNode, e.g.

```
let obj: React.ReactNode = {};
let func: React.ReactNode = () => {};
```

This was by mistake, and this PR mutes most of such cases by simply
casting to a `string` or `ReactNode`.
In some cases, it is worth to follow up and address the raised issues in
a better way (see in comments)


```diff

function MyComponent() {

const error: string | Error = 'Error'

return (
  <div>
-   {error}
+   {error as string}
  </div>
)

}

```


Most common problems are related to rendering errors, where it could be
`string | Error` object rendered directly as a ReactNode. Most often it
is related to alerting framework:

```
export interface RuleFormParamsErrors {
  [key: string]: string | string[] | RuleFormParamsErrors;
}
```

Not sure if there is a better fix then casting, surely not short-term. 

### 2 More `useCallback` implicit any fixes

Follow up to https://github.com/elastic/kibana/pull/191659

### 3 `EuiSelect` doesn't have a placeholder prop 

In a couple of places, the `placeholder` prop was removed. This is
because react types were updated and `placeholder` was removed from the
base HTML element, so it highlighted places where `placeholder` prop was
redundant
2024-09-12 13:54:18 +02:00

68 lines
2.3 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import React, { useCallback } from 'react';
import { useState } from 'react';
import { EuiText, EuiButton, EuiLoadingSpinner, EuiCallOut } from '@elastic/eui';
import { type IHttpFetchError, isHttpFetchError } from '@kbn/core-http-browser';
import { Services } from './services';
interface Props {
fetchRandomNumber: Services['fetchRandomNumber'];
}
export function RandomNumberRouteExample({ fetchRandomNumber }: Props) {
const [error, setError] = useState<IHttpFetchError | undefined>(undefined);
const [randomNumber, setRandomNumber] = useState<number>(0);
const [isFetching, setIsFetching] = useState<boolean>(false);
const doFetch = useCallback(async () => {
if (isFetching) return;
setIsFetching(true);
const response = await fetchRandomNumber();
if (isHttpFetchError(response)) {
setError(response);
} else {
setRandomNumber(response);
}
setIsFetching(false);
}, [isFetching, fetchRandomNumber]);
return (
<React.Fragment>
<EuiText>
<h2>GET example</h2>
<p>
This examples uses a simple GET route that takes no parameters or body in the request and
returns a single number.
</p>
<EuiButton
data-test-subj="routingExampleFetchRandomNumber"
disabled={isFetching}
onClick={() => doFetch()}
>
{isFetching ? <EuiLoadingSpinner /> : 'Generate a random number'}
</EuiButton>
{error !== undefined ? (
<EuiCallOut color="danger" iconType="warning">
{JSON.stringify(error)}
</EuiCallOut>
) : null}
{randomNumber > -1 ? (
<h2>
Random number is <div data-test-subj="routingExampleRandomNumber">{randomNumber}</div>
</h2>
) : null}
</EuiText>
</React.Fragment>
);
}