UseState和useContext不会触发重新渲染

时间:2020-08-31 17:26:01

标签: javascript reactjs react-hooks

我正在开发一个将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

我不确定我在做什么错。

任何帮助都是有用的。

1 个答案:

答案 0 :(得分:0)

如果使用“ useContext”,则不需要“消费者”。此外,您不会使用'consumer'的arg'context'。因此,请尝试不要使用“消费者”