Home > Net >  React button onClick not working when I removed unrelated elements
React button onClick not working when I removed unrelated elements

Time:10-09

So I was working on building functionality for a table on this practice application i'm working on and I started having some weird issues with my buttons not working. In it's current state, the button in the table works, but the button at the top of the page does not work. If I delete the button at the top of the page the button in the table will stop working. The button in the table will also stop working if I remove any of the other 's in the table. I'm pretty stumped as to what could be causing this. If I place any or either of the buttons into the custom Sidebar component they work just fine. I'm new to using hooks so i'm wondering if it's some kind of scope or binding issue but I can't find any results that seem to match this issue using functional components. Apologies for the long file, the top button is at the top near the return statement, the table button is at the bottom of the table towards the bottom of the returned div.

Edit: Here is a link to the project in codesandbox.io I had to rip out the sign in process which hopefully wasn't related In codesandbox.io the top button still doesn't work unless it's in the sidebar but it does not affect the bottom button

https://codesandbox.io/s/inspiring-lichterman-i2688?file=/src/components/Dashboard.js:2867-2924

import {auth} from "../firebase";
import Sidebar from 'react-sidebar'
import menuImage from '../resources/menu.png'
import profileImage from '../resources/profile.png'
import chart from '../resources/piechart.jpeg'
import IncomeModal from './IncomeModal.js';
import './Dashboard.css'


const Dashboard = () => {

  const [sidebarOpen, setSidebarOpen] = useState(true)
  const [userData, setUserData] = useState(null)
  const [isLoading, setIsLoading] = useState(true)
  const [isIncomeModal, setIncomeModal] = useState(false)
  const [newIncome, setNewIncome] = useState(0)
  const [submissionInProgress, setSubmissionInProgress] = useState(false)
  const [purchaseArray, setPurchaseArray] = useState([])

  function showIncomeModal() {
    setSidebarOpen(false)
    return setIncomeModal(true)
  }
  
  function hideIncomeModal() {
    return setIncomeModal(false)
  }

  const onChangeHandler = (event) => {
    const {name, value} = event.currentTarget;
    if(!submissionInProgress) {
      if(name === 'newIncome') {
        setNewIncome(value);
      }
    }
}

async function postNewIncome(newIncomeVal) {
  let url = `placeholder`
  let newIncomeNumber = Number(newIncomeVal)
  let testBody = {
    uid: auth.currentUser.uid,
    newIncome: newIncomeNumber
  }
  console.log(testBody)
  const response = await fetch(url, {
      method: 'POST',
      headers: {
          clientSecret: 832195,
          'Content-Type': 'application/json'
      },
      body: JSON.stringify(testBody)
  })
  return response; 
}

function submitNewIncome() {
  if(submissionInProgress) {
    return
  } else {
    setSubmissionInProgress(true)
    postNewIncome(newIncome).then(()=> {
      hideIncomeModal()
      refreshUserData()
      setSidebarOpen(true)
      setSubmissionInProgress(false)
    })
  }
}

function refreshUserData() {
  setIsLoading(true)
  getUser().then(data => {
    setUserData(data)
  }).catch(error => {
    console.error('error fetching user data:', error)
  }).finally(()=> {
    setIsLoading(false)
  })
}

function deletePurchase(index) {
  console.log(index)
}

  useEffect(() => {
    refreshUserData()
  }, userData)

  const navButtonStyle = {
      backgroundColor: '#082032',
      borderTop: '2px solid #334756',
      borderBottom: '2px solid #334756',
      borderLeft: 'none',
      borderRight: 'none',
      color: '#FF4C29',
      width: '100%',
      padding: '5px'
  }

  let username = 'loading...'
  let income = 'loading'
  if(!isLoading) {
    username = userData.username
    income = `$${userData.income} / month`
  }

  return (
    <div>
      <h1 className='title'>Dashboard</h1>
      <button onClick={() => console.log('test')}>test</button>
      <Sidebar
        sidebar={
          <div>
          <img style={{display: 'block', marginLeft: 'auto', marginRight: 'auto', marginTop:'10px'}} src={profileImage} />
          <h2 style={{color: '#FF4C29', textAlign: 'center'}}>{username}</h2>
          <div style={{backgroundColor: '#082032', padding:'1px'}}>
          <h3 style={{color: '#FF4C29', textAlign: 'center'}}>Income:<br/>{income}</h3>
          </div>
          <button style={navButtonStyle} onClick = {() => showIncomeModal()}>Set Income</button>
          <button style={navButtonStyle} onClick = {() => {auth.signOut()}}>Sign out</button>
          </div>
        }
        open={sidebarOpen}
        onSetOpen={setSidebarOpen}
        styles={{ sidebar: { background: '#2C394B', width: '15%' } }}>
        <button className='menuButton' onClick={() => setSidebarOpen(true)}>
          <img style={{margin: '10px', width: '40px'}} src={menuImage} />
        </button>
      </Sidebar>
      <div className='dashboard'>
        <div className='display'>
          <img style={{display: 'block', marginLeft: 'auto', marginRight: 'auto'}} src={chart} />
        </div>
        <br/>
        <div className='flexbox'>
          <div className='flexdisplay'>
            <h3>Purchases</h3>
            <table>
              <tr>
                <th>Name</th>
                <th>Cost</th>
                <th></th>
              </tr>
              <tr>
                <td>ark</td>
                <td>$15.00</td>
              </tr>
              <tr>
                <td>ark</td>
                <td>$15.00</td>
              </tr>
              
              
              
              
        
        
              
              <tr>
                <td>last</td>
                <td>$16.00</td>
                <td><button onClick={() => console.log('value')}>x</button></td>
              </tr>
            </table>
          </div>
          <div className='flexdisplay'>
             <p>Recurring Expenses</p>
            <img style={{display: 'block', marginLeft: 'auto', marginRight: 'auto'}} src={chart} />
          </div>
        </div>
      </div>
      <IncomeModal show={isIncomeModal} handleClose={hideIncomeModal}>
        <h1>Update Income</h1>
        <input 
            type='number'
            name="newIncome"
            value = {newIncome}
            placeholder=""
            id="newIncomeInput"
            style={{margin: 10}}
            onChange = {(event) => onChangeHandler(event)}
        />
        <button onClick={() => submitNewIncome()}>Submit</button>
      </IncomeModal>
    </div>
  ) 
};

async function getUser() {
  let uid = auth.currentUser.uid
  let url = `placeholder`
  const response = await fetch(url, {
      method: 'GET',
      headers: {
          clientSecret: 832195
      }
  })
  return response.json(); 
}

// async function setIncome() {

// }


export default Dashboard;```

CodePudding user response:

It isn't an issue with react but your styles. If you try to Inspect(Ctrl shift C on chrome) the button element outside the sidebar, you'll find that it is overlapped, hence no click is passed to it.

In your codesandbox example, following resets the overlapping divs

document.querySelector('div[role=navigation]>div:nth-child(3)').style.inset='unset'
document.querySelector('div[role=navigation]').style.inset='unset'

The combination of position: absolute and inset: 0px is making these components span the entire width. As workaround, I removed the inset but you should better redefine the CSS in a better way.

  • Related