事件流

层叠上下文
若子元素的层叠上下文在父元素下方,那么点击子元素位置时target只能到父元素这,即子元素无法触发到点击监听
若子元素的层叠上下文在父元素下方,那么点击子元素位置时target只能到父元素这,即子元素无法触发到点击监听
import React, { FC, useRef } from 'react'
import copy from 'copy-to-clipboard'
import { message } from 'hljd'
import { debounce } from 'lodash'
interface ColorPickerInputNativeProps {
value?: string
onChange?: (value: string) => void
}
const ColorPickerInputNative: FC<ColorPickerInputNativeProps> = ({ value, onChange }) => {
const eRef = useRef('')
const funcRef = useRef(
debounce(() => {
copy(eRef.current)
onChange?.(eRef.current)
message.success('颜色值已复制')
}, 200)
)
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
eRef.current = e.target.value
funcRef.current()
}
return <input type="color" value={value} onChange={handleChange} />
}
export { ColorPickerInputNative }
要点:
grid-auto-flow:流动方向,可以设定row或column,类似于flex-direction。
auto-flow:可以在grid中设置缩写
gird: <grid-template-rows> / [auto-flow && dense?] <grid-auto-columns>
grid: <auto-flow && dense?> <grid-auto-rows> / <grid-template-rows>
在左侧说明是row,在右侧说明是column,与grid-auto-flow有相同的作用。
例如
grid:auto-flow dense 300px/200px 1fr
上述代码说明有两列为200px和1fr,然后稠密的向下流动,只有匿名单元格,匿名单元格的高度为300px。
计数以1开始,包括边缘线,就是说如果水平有6块,则计数可以从1~7,可以是负数-1是右侧边缘线,可以从-7~-1
grid-column-start 与 grid-column-end 不需要考虑前者的数字比后者大或小。
let [count, setCount] = useState(0)
let intervalCb = useRef(null)
let CountTimer
useEffect(() => {
intervalCb.current = () => {
setCount(count+1)
}
}, [count])
useEffect(() => {
function itvFn() {
intervalCb.current()
}
CountTimer = window.setInterval(itvFn, 1000)
return () => window.clearInterval(CountTimer)
}, [])
const handleStop = () => { // 暂停
window.clearInterval(CountTimer)
}
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [data, setData] = useState({ hits: [] });
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'https://hn.algolia.com/api/v1/search?query=redux',
);
setData(result.data);
};
fetchData();
}, []);
return (
<ul>
{data.hits.map(item => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
);
}
export default App;
function App() {
const [data, setData] = useState({ hits: [] });
const [query, setQuery] = useState('redux');
const [url, setUrl] = useState(
'https://hn.algolia.com/api/v1/search?query=redux',
);
useEffect(() => {
const fetchData = async () => {
const result = await axios(url);
setData(result.data);
};
fetchData();
}, [url]);
return (
<Fragment>
<input
type="text"
value={query}
onChange={event => setQuery(event.target.value)}
/>
<button
type="button"
onClick={() =>
setUrl(`http://hn.algolia.com/api/v1/search?query=${query}`)
}
>
Search
</button>
<ul>
{data.hits.map(item => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
</Fragment>
);
}
import React, { Fragment, useState, useEffect } from 'react';
import axios from 'axios';
const useDataApi = (initialUrl, initialData) => {
const [data, setData] = useState(initialData);
const [url, setUrl] = useState(initialUrl);
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
useEffect(() => {
const fetchData = async () => {
setIsError(false);
setIsLoading(true);
try {
const result = await axios(url);
setData(result.data);
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
fetchData();
}, [url]);
return [{ data, isLoading, isError }, setUrl];
};
function App() {
const [query, setQuery] = useState('redux');
const [{ data, isLoading, isError }, doFetch] = useDataApi(
'https://hn.algolia.com/api/v1/search?query=redux',
{ hits: [] },
);
return (
<Fragment>
<form
onSubmit={event => {
doFetch(
`http://hn.algolia.com/api/v1/search?query=${query}`,
);
event.preventDefault();
}}
>
<input
type="text"
value={query}
onChange={event => setQuery(event.target.value)}
/>
<button type="submit">Search</button>
</form>
{isError && <div>Something went wrong ...</div>}
{isLoading ? (
<div>Loading ...</div>
) : (
<ul>
{data.hits.map(item => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
)}
</Fragment>
);
}
export default App;
setState的第一个参数可以传入函数,函数中的第一个参数是state的值
– createRef 每次渲染都会返回一个新的引用 – useRef 每次都会返回相同的引用
const child1 = useMemo(() => <Child1 count={count} />, [count])