ブログ内検索機能を改善した
2020-12-05
Improved the search function.
実装した検索機能の問題点
前回、ブログ内検索を実装しました。高速で検索結果が表示されるのが楽しいので時々触っています。ですが検索結果が表示されたままになってしまうので、ブログの見た目をそれっぽくしたいという目的はイマイチ達成できていませんでした。キーワードを入れると検索結果が表示される
ここまではいい
テキストフィールドの外に出ても結果が表示されたままになる
これはあかん
画像だとわかりにくいので動画を用意しました
というわけで直しました
画像だとわからないので動画にしました。テキストフィールドからフォーカスがはずれると検索結果が非表示になります。
追加したコード
src\components\Search\index.jsx
変更前
const Search = props => {
const [focus, setFocus] = useState(false)
const [value, setValue] = useState("")
const onFocus = () => {
setFocus(true)
}
const onBlur = () => {
setFocus(false)
}
const onChange = e => {
setValue(e.target.value)
}
return (
<div>
<TextField
id="outlined-search"
label="ブログ内検索..."
type="search"
variant="outlined"
onFocus={onFocus}
onBlur={onBlur}
onChange={onChange}
/>
<SearchResult focus={focus} value={value} />
</div>
)
}
onFocusとonBlurを使ってフォーカスが当たった/はずれたの判定は前回の時点で作成済みです。なのでfocus
を三項演算子で評価してtrueなら検索結果を表示するようにしました。
変更後
const Search = props => {
const [focus, setFocus] = useState(false)
const [value, setValue] = useState("")
const onFocus = () => {
setFocus(true)
}
const onBlur = () => {
setFocus(false)
}
const outFocus = () => {
setTimeout(onBlur, 100)
}
const onChange = e => {
setValue(e.target.value)
}
return (
<div>
<TextField
id="outlined-search"
label="ブログ内検索..."
type="search"
variant="outlined"
onFocus={onFocus}
onBlur={outFocus}
onChange={onChange}
/>
{focus ? <SearchResult focus={focus} value={value} />: null}
</div>
)
}
前回のコードのまま処理を入れてしまうとうまく動きません。検索結果をクリックするとその時点でフォーカスがはずれて、リンクを開く前に非表示になってしまいます。なのでsetTimeout
を使ってディレイを入れています。
const outFocus = () => {
setTimeout(onBlur, 100)
}
あとはonBlur
イベントで呼び出す処理を、新しく作ったoutFocus
に変更します。
<TextField
id="outlined-search"
label="ブログ内検索..."
type="search"
variant="outlined"
onFocus={onFocus}
onBlur={outFocus} {/* ここを変更 */}
onChange={onChange}
/>
検索結果の表示も調整します。<Card>
を追加しただけです。
import Card from '@material-ui/core/Card';
return (
<div>
<ul>
{result.map(e => {
return (
<li key={e.slug}>
<Link to={`/${e.path}/`}>
<Card>
<TextHighlighter str={e.title} includes={props.value} />
</Card>
</Link>
</li>
)
})}
</ul>
</div>
)
以上です。