我正在开发一个将useState作为上下文提供程序中的值传递的应用程序。该代码如下面的代码所示。
//App.js
import React,{useState,useContext} from 'react';
import logo from './logo.svg';
// import './App.css';
// import '../src/assets/tailwind.css'
import OneNote from '../src/components/onenote'
import OneNoteChild from '../src/components/OneNoteChild'
import HomePage from '../src/components/HomePage'
import { useFormik } from 'formik';
import {SearchProvider,SearchConsumer} from '../src/SearchCon';
const algoliasearch = require("algoliasearch");
const client = algoliasearch("asdasd", "code here");
const index = client.initIndex("articles");
async function Searh(term){
var t = await index
.search(term)
.then(({ hits }) => {
// console.log(hits);
return hits
})
.catch(err => {
console.log(err);
});
return t;
}
function App() {
const [hit, setHit] = useState('')
const [searchItems, setsearchItems] = useState([])
const formik = useFormik({
initialValues: {
search: '',
},
onSubmit: values => {
setsearchItems([])
var temp = index
.search(values.search,{hitsPerPage:100})
.then(({ hits }) => {
// console.log(hits);
// return hits
setHit(hits)
})
.catch(err => {
console.log(err);
});
// var hits = Searh(values.search)
// console.log(hits)
// setHit(hits)
},
});
return (
<SearchProvider value={[searchItems, setsearchItems]}>
<div className="App" class="bg-gray-200 font-light font-serif p-4">
<form onSubmit={formik.handleSubmit} class='pr-8 pl-8 mt-8' class='sticky'>
<input
id="search"
name="search"
type="search"
onChange={formik.handleChange}
value={formik.values.search}
class="bg-white focus:outline-none focus:shadow-outline border border-gray-300 rounded-lg py-2 px-4 block w-full appearance-none leading-normal"
/>
</form>
<HomePage hit={hit}/>
</div>
</SearchProvider>
);
}
export default App;
现在,主页分为两个部分。第一部分显示搜索结果,如下面的代码所示(OneNote.js是显示结果的文件)。 OneNote部分中显示的代码将呈现文本。文本中的每个单词都是可单击的。此单击会导致状态中的其他元素向下传递到上下文。由于在状态中添加了新元素,因此呈现了新元素。渲染代码位于下面的HomePage.js文件的SearchCon.Consumer部分。
//HomePage.js
import React,{useContext} from 'react'
import SearchCon,{SearchConsumer} from '../SearchCon'
import OneNote from './onenote'
import OneNoteChild from './OneNoteChild'
function HomePage(props){
const [searchItems, setsearchItems] = useContext(SearchCon);
return (
<div class='flex overflow-x-hidden text-base'>
<div class='flex text-base grid-flow-row w-1/3 border-r-2 border-gray-500'>
<div class="divide-y divide-gray-400 pr-1 pl-1 max-w-lg">
{props.hit===''?<></>:props.hit.map((item)=>
<OneNote key={item.objectID} ol={item}/>
)}
</div>
</div>
<SearchCon.Consumer>
{context=>
<div class='w-2/3 flex overflow-auto text-gray-600'>
{
searchItems.length>0?searchItems.map((item)=><OneNoteChild word={item}/>):<></>
}
</div>}
</SearchCon.Consumer>
</div>
)
}
export default HomePage;
下面的文件是OneNote.js,该文件在首页中用于显示搜索结果。
//OneNote.js
import React,{useContext} from 'react'
import SearchCon from '../SearchCon'
const algoliasearch = require("algoliasearch");
const client = algoliasearch("asdf", "adfad");
const index = client.initIndex("articles");
function OneNote(props){
const [searchItems, setsearchItems] = useContext(SearchCon);
console.log(props)
var all = props.ol.text.split(' ')
function GD(wrd){
if(searchItems.length<1){
setsearchItems([wrd])
}else{
var temp = searchItems
console.log(searchItems)
console.log(typeof(temp))
temp.push(wrd)
setsearchItems(temp)
}
}
return <div class=' p-6' key={props.ol.objectID}>
{all.map((word)=><><button class='bg-gray-200 border-gray-200' onClick={()=>GD(word)}>{word}</button>{" "}</>)}
</div>
}
export default (OneNote);
现在我面临的问题是,单击OneNoteChild呈现的文本时(上下文在下面),上下文不会立即更新。仅当我在App.js文件的输入中键入内容后,它才会触发上下文更改并导致重新渲染。
//OneNoteChild.js
import React,{useContext,useState} from 'react'
import SearchCon from '../SearchCon'
import SearchResItem from '../components/SearchResItem'
const algoliasearch = require("algoliasearch");
const client = algoliasearch("asdfadsfa", "adsfadf");
const index = client.initIndex("articles");
function OneNoteChild(props){
const [searchItems, setsearchItems] = useContext(SearchCon);
const [res, setres] = useState("")
if(res===''){
var temp = index
.search(props.word,{hitsPerPage:100})
.then(({ hits }) => {
setres(hits)
})
.catch(err => {
console.log(err);
});
}
if(res===''){
return <div>Loading</div>
}
function Wrd(){
var temp = [];
for (let index = 0; index < searchItems.length; index++) {
const element = searchItems[index];
if(element===props.word){
}else{
temp.push(element)
}
}
setsearchItems(temp)
}
return <div class='p-6 divide-y divide-gray-400 w-78 border-black shadow-xl m-2' >
{props.word}<button className='float-right' onClick={Wrd}>x</button><br/>
{res.length>0?res.map((item)=><SearchResItem ol={item} word={props.word}/>):<div>No Results</div>}
</div>
}
export default (OneNoteChild);
//SearchResItem.js
import React,{useContext} from 'react'
import SearchCon from '../SearchCon'
function SearchResItem(props){
const [searchItems, setsearchItems] = useContext(SearchCon);
var all = props.ol.text.split(' ')
function GD(wrd){
//Add this word
console.log('Add')
if(searchItems.length<1){
setsearchItems([wrd])
}else{
var temp = searchItems
console.log(temp)
console.log(typeof(temp))
temp.push(wrd)
setsearchItems(temp)
}
}
return <div class='p-2 w-70'>
{all.map((word)=><><button class='bg-gray-200 border-gray-200' onClick={()=>GD(word)}>{word===props.word?<div class='text-blue-600'>{word}</div>:word}</button>{" "}</>)}
<br/><a href={props.ol.url} target='_blank' class='text-red-400'>Link</a>
</div>
}
export default (SearchResItem);
//SearchCon.js
import React from 'react'
const SearchCon = React.createContext()
export const SearchProvider = SearchCon.Provider
export const SearchConsumer = SearchCon.Consumer
export default SearchCon
我不确定我在做什么错。
任何帮助都是有用的。
答案 0 :(得分:0)
如果使用“ useContext”,则不需要“消费者”。此外,您不会使用'consumer'的arg'context'。因此,请尝试不要使用“消费者”