Javascript 减速器/上下文Api

Javascript 减速器/上下文Api,javascript,json,reactjs,redux,Javascript,Json,Reactjs,Redux,所以我用reducer创建了一个上下文。我有一些逻辑,理论上应该是可行的。我有一个Show组件,它迭代data.js中的数据,并有一个按钮。我还有一个windows组件,它迭代数据。无论如何,问题是当我单击Show Component中的按钮时,它应该删除Windows组件和Show组件中data.js的项/id,但当我单击它时,什么也没有发生。如果有人能帮助我,我将非常感激。问候 App.js const App =()=>{ const[isShowlOpen, setIs

所以我用reducer创建了一个上下文。我有一些逻辑,理论上应该是可行的。我有一个Show组件,它迭代data.js中的数据,并有一个按钮。我还有一个windows组件,它迭代数据。无论如何,问题是当我单击Show Component中的按钮时,它应该删除Windows组件和Show组件中data.js的项/id,但当我单击它时,什么也没有发生。如果有人能帮助我,我将非常感激。问候

App.js 

const App =()=>{

   const[isShowlOpen, setIsShowOpen]=React.useState(false)

   const Show = useRef(null)

    function openShow(){
      setIsShowOpen(true)
    }
    function closeShowl(){
      setIsShowOpen(false)
    }


const handleShow =(e)=>{
      if(show.current&& !showl.current.contains(e.target)){
        closeShow() 
      }
    }
    useEffect(()=>{
        document.addEventListener('click',handleShow)
          return () =>{
           document.removeEventListener('click', handleShow)
          }   
      },[])
 return (
  <div>

  <div ref={show}>
    <img  className='taskbar__iconsRight'  onClick={() => 
     setIsShowOpen(!isShowOpen)} 
       src="https://winaero.com/blog/wp-content/uploads/2017/07/Control- 
        -icon.png"/>
          {isShowOpen ? <Show  closeShow={closeShow}  />: null}
   </div>
)
}
```Context```
import React, { useState, useContext, useReducer, useEffect } from 'react'
import {windowsIcons} from './data'
import reducer from './reducer'

const AppContext = React.createContext()

const initialState = {
icons: windowsIcons
}

const AppProvider = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, initialState)

  const remove = (id) => {
    dispatch({ type: 'REMOVE', payload: id })
  }
 
  return (
    <AppContext.Provider
      value={{ 
        ...state,
        remove,       
      }}
      >
      {children}
    </AppContext.Provider>
  )
}

export const useGlobalContext = () => {
  return useContext(AppContext)
}

export { AppContext, AppProvider }



reducer.js
const reducer = (state, action) => {  
    if (action.type === 'REMOVE') {
      return {
        ...state,
        icons: state.icons.filter((windowsIcons) => windowsIcons.id !== action.payload),
      }
    }
}

export default reducer

``data.js```
export const windowsIcons =[
  { 
     id:15,
     url:"something/",
     name:"yes",
     img:"/images/icons/crud.png",
    },
    {
        id:16,
        url:"something/",
        name:"nine",
        img:"/images/icons/stermm.png",
       },
       {
        id:17,
        url:"domething/",
        name:"ten",
        img:"/images/icons/ll.png",
       },
       {
        id:18,
        url:"whatever",
        name:"twenty",
        img:"/images/icons/icons848.png",
       },
       {
        id:19,
        url:"hello",
        name:"yeaa",
        img:"/images/icons/icons8-96.png",
       },
    ]


``` Show Component```
import React from 'react'
import { useGlobalContext } from '../../context'
import WindowsIcons from '../../WindowsIcons/WindowsIcons'
const Show = () => {
  const { remove, } = useGlobalContext() 

    return (
        <div className='control'>
          {windowsIcons.map((unin)=>{       
            const { name, img, id} = unin  
            return (             
             <li className='control' key ={id}>
               <div className='img__text'> 
               <img className='control__Img' src={img} />             
                <h4 className='control__name'>{name}</h4>
               </div>
                <button className='unin__button' onClick={() => remove(id)} >remove</button>                 
              </li> )
        </div>
    )
}

export default Show


import React from 'react'
import {windowsIcons} from "../data"
import './WindowsIcons.css'
const WindowsIcons = ({id, url, img, name}) => {
    return (
        <>
               {windowsIcons.map((icons)=>{
            const {id, name , img ,url} =icons
            return(
                <div className='windows__icon' >
                  <li className='windows__list' key={id}>
                    <a href={url}>
                     <img className='windows__image' src={img}/>                                                        
                     <h4 className='windows__text'>{name}</h4>                   
                    </a>
                  </li>     
                </div>          
            )
        })}                   
        </>
    )
}
App.js
常量应用=()=>{
常量[IsShowOpen,setIsShowOpen]=React.useState(false)
const Show=useRef(空)
函数openShow(){
setIsShowOpen(真)
}
函数closeShowl(){
setIsShowOpen(假)
}
常量handleShow=(e)=>{
if(show.current&!showl.current.contains(e.target)){
closeShow()
}
}
useffect(()=>{
document.addEventListener('click',handleShow)
return()=>{
document.removeEventListener('click',handleShow)
}   
},[])
返回(
{isShowOpen?:null}
)
}
```上下文```
从“React”导入React,{useState,useContext,useReducer,useEffect}
从“/data”导入{windowsIcons}
从“./reducer”导入减速机
const AppContext=React.createContext()
常量初始状态={
图标:窗口图标
}
const AppProvider=({children})=>{
const[state,dispatch]=useReducer(reducer,initialState)
常量删除=(id)=>{
分派({type:'REMOVE',负载:id})
}
返回(

)
})}                   
)
}
问题 在reducer中,您正在为数据列表设置初始状态。
这是完全正确的

但是,在
Show
组件中,直接导入
windowsIcons
并在其上循环渲染。因此,您不再在减速器正在处理的状态上循环。如果状态改变,您将看不到它

解决方案 相反,在Show组件中,循环显示减速器中的状态:

const { remove, icons } = useGlobalContext()

{icons.map((unin) => {
  // Render stuff
}
现在,如果单击“删除”,它将修改内部状态,
图标
变量将得到更新


它在某种程度上起作用,想象一下你有一个导航栏,它有切换功能和外部点击功能。所以每次我点击移除按钮,导航栏就会关闭,我不想这样。我添加/更新了应用程序组件的代码,我在其中呈现了不属于原始问题一部分的Show组件。。。问题是,当我单击Show Component中的按钮时,它应该删除Windows组件和Show组件中data.js的项/id,但当我单击它时,什么都没有发生。。。我的答案解决了在您的上下文中从状态中删除项目的问题。