#StackBounty: #javascript #reactjs #react-hooks Using Location State in Functional Component

Bounty: 50

I’m working on a React project that requires the app URL to be fully-declared, static and immutable, so just:

https://exampleurl.com/path/to/app/index.html

..but none of the following:

https://exampleurl.com/path/to/app/

https://exampleurl.com/path/to/app/index.html?query=value

https://exampleurl.com/path/to/app/subdir/index.html

So, the project uses state and withRouter to provide basic app navigation. The responsible component is as follows:

import React from 'react';
import { withRouter} from "react-router-dom";
import RenderNav from './RenderNav';
import Cohort from '../view/Cohort';
import Holdings from '../view/Holdings';
import Policy from '../view/Policy';
import Search from '../view/Search';
import Start from '../view/Start';
import Training from '../view/Training';
import WatchList from '../view/WatchList';

class RenderDisplay extends React.Component {
  constructor(props) {
    super(props);
    this.state = this.props.location.state || { activeDisplay: 'start' };
    this.props.history.replace(this.props.location.pathname, this.state);
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.props.location !== prevProps.location) {
      this.setState(this.props.location.state);
    }
  }

  setDisplay() {
    let displayMode = [];
    let d = this.state.activeDisplay;

    switch(d) {
      case 'start': displayMode = [
        <Start key={`display-${d}`} />
      ]; break;

      // ...and so on - activeDisplay determines displayMode (and so screen contents)

      default: displayMode = [<div>Error</div>]; break;
    }; return displayMode;
  }

  render() {
    return (
      <div className="container">
        {this.setDisplay()}
      </div>
    );
  }
}

export default withRouter(RenderDisplay);

The location.state object is set by the <Link /> component:

<Link to={{ state: {activeDisplay: 'start'} }}>
  <button type="button">Home</button>
</Link>

The result is normal browser navigation throughout the app while the URL remains unchanged.

My question is: how can the class-based RenderDisplay component above be converted to a functional component (using hooks)?

I’ve tried several permutations of useEffect, useState, and useLocation, but I clearly don’t understand hooks well enough to reproduce the behavior of the class-based component above.


Get this bounty!!!

#StackBounty: #reactjs #react-hooks #use-context #createcontext How to pass a value using `createContext` from parent to child's ch…

Bounty: 50

Instead of passing props from parent to child1(parent of child2) ->to child2,
I want to use createContext and receive the value with useContext.

What I tried to do is not correct because and I’m getting an error **'booleanContext' is not defined**.

How can I pass the createContext state/value ?

App.js

CreatePass is a component inside SignUp

  const [signUpFirst, setIfSignUp] = useState(true);
  const booleanContext = createContext(setIfSignUp);
  
 return (
    <booleanContext.Provider value={setIfSignUp}>

   <div>
     </Switch>
   <Route exact path='/signup'>
          <SignUp homePage={exitSignUpPage} setUserNumber={setUserID} />
        </Route>
        <Route exact path='/home'>
          <Home userIDNumber={userID} setIfSignUp={setIfSignUp} />
        </Route>
      <CreatPass /> 
      </Switch>
     </div>
    </booleanContext.Provider>
  );

SignUp.js

  render() {
    return (
      <div className='signUp-div'>
        <Header />
        <Router history={history}>
          <div className='form-div'>
            <Redirect to='/signup/mobile' />
            <Switch>
              <Route exact path='/signup/mobile' component={MobileNum} />
              <Route exact path='/signup/idnumber'>
                <IdentNumber setPersonalID={this.props.setUserNumber} />
              </Route>
              <Route exact path='/signup/password'>
                <CreatePass />
              </Route>
            </Switch>
          </div>
        </Router>
      </div>
    );
  }

CreatePass.js //'booleanContext' is not defined no-undef

const CreatePass = () => {
  const changeBooleanValue = useContext(booleanContext);

  const handleClickButton = () => {
      changeBooleanValue(true);
  };

  return (
    <div className='form-div'>
  <button onClick={handleClickButton}>Click</button>
    </div>
  );
};
export default CreatePass;

Edit – Update:

This solution is not good it’s the same value as I did above booleanContext is undefined –

export const booleanContext = createContext(); // default value is undefiend
...
const App = () => 
     return(
     <booleanContext.Provider value={setIfSignUp}>
      <CreatPass />        
     </booleanContext.Provider>
      )
}
export default App;

Will be glad for explanations


Get this bounty!!!

#StackBounty: #javascript #reactjs #typescript #styled-components Circular definition of import alias 'theme'

Bounty: 50

I am trying to extend the theme of a third party private npm module. The project compiles successfully but I keep getting a typescript error Circular definition of import alias 'externalTheme'

Below is how I am extending the theme. This is working perfectly in the way that it is using both my theme and the external theme combined

import { externalTheme, ExternalThemeInterface } from 'external-npm-repo...'

import { colors, ColorsTypes } from './colors'

export const MyTheme: MyThemeInterface = {
    ...theme,
    colors,
}

export interface MyThemeInterface extends ExternalThemeInterface {
    colors: ColorsTypes
}

The error I am getting is referencing circular dependency with the externalTheme import, im not sure what this exactly means and havent found any clear references when researching.

These are my Typescript settings

        "allowJs": true,
        "alwaysStrict": true,
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "isolatedModules": true,
        "jsx": "preserve",
        "lib": ["dom", "es2017"],
        "module": "esnext",
        "moduleResolution": "node",
        "noEmit": true,
        "noFallthroughCasesInSwitch": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "resolveJsonModule": true,
        "skipLibCheck": true,
        "strict": true,
        "target": "esnext"


Get this bounty!!!

#StackBounty: #javascript #reactjs #jestjs #enzyme expect(jest.fn()).toHaveBeenCalled() Expected number of calls: >= 1 Received numb…

Bounty: 200

I have a component that gets form data and dispatch an action with data. This action eventually makes an ajax request to the server to send that data using javascript fetch function.

import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Editor } from 'react-draft-wysiwyg';
import { EditorState } from 'draft-js';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
import { getCookie } from '../../../utils/cookies';

import { postJobAction } from './redux/postJobActions';

const PostJobComponent = () => {
  const dispatch = useDispatch();
  const [editorState, setEditorState] = useState(() => EditorState.createEmpty());
  const [department, setDepartment] = useState('');

  const postJob = (event) => { // Here is happens and I am testing this function now.
    event.preventDefault();

    const jobPosterId = getCookie('id');
    const title = event.target.title.value;
    const location = event.target.location.value;
    const jobDescription = editorState.getCurrentContent().getPlainText();

    dispatch(postJobAction({
      jobPosterId,
      title,
      location,
      department,
      jobDescription,
    }));
  };

  const onDepartmentChange = (event) => {
    setDepartment(event.target.value);
  };

  return (
    <div className='post-job'>
      <form onSubmit={postJob}>
        <div>
          <label>Job Title</label>
          <input
            type='text'
            name='title'
            defaultValue=''
            className='job__title'
            placeholder='e.g. Frontend Developer, Project Manager etc.'
            required
          />
        </div>
        <div>
          <label>Job Location</label>
          <input
            type='text'
            name='location'
            defaultValue=''
            className='job__location'
            placeholder='e.g. Berlin, Germany.'
            required
          />
        </div>
        <div>
          <label>Department</label>
          <select className='job__department' required onChange={onDepartmentChange}>
            <option value=''>Select</option>
            <option value='Customer Success'>Customer Success</option>
            <option value='Professional Services'>Professional Services</option>
            <option value='Service Support'>Service And Support</option>
          </select>
        </div>
        <div style={{ border: '1px solid black', padding: '2px', minHeight: '400px' }}>
          <Editor
            required
            editorState={editorState}
            onEditorStateChange={setEditorState}
          />
        </div>
        <div>
          <button>Save</button>
        </div>
      </form>
    </div>
  );
};

export default PostJobComponent;

Here is the test in jest and enzyme for postJob function.

it('should submit job post form on save button click', () => {
        const onPostJobSubmit = jest.fn();
        const instance = wrapper.instance();
        wrapper.find('form').simulate('submit', {
      target: {
        jobPosterId: {
            value: '12312jkh3kj12h3k12h321g3',
        },
        title: {
          value: 'some value',
        },
        location: {
          value: 'some value',
        },
        department: {
            value: 'Customer',
        },
        jobDescription: {
            value: 'This is Job description.',
        },
      },
    });
        expect(onPostJobSubmit).toHaveBeenCalled();
    });

The code works perfectly fine but the tests are failing with below error.

expect(jest.fn()).toHaveBeenCalled()

    Expected number of calls: >= 1
    Received number of calls:    0

       98 |       },
       99 |     });
    > 100 |         expect(onPostJobSubmit).toHaveBeenCalled();
          |                                 ^
      101 |     });
      102 | });
      103 |

      at Object.<anonymous> (src/components/employer/jobs/postJob.test.js:100:27)

Here is the action for postJob function that dispatches action.

export const postJobAction = (payload) => {
  return {
    type: 'POST_JOB_REQUEST',
    payload,
  }
};

Here is the saga.

import { put, call } from 'redux-saga/effects';
import { postJobService } from '../services/postJobServices';

export function* postJobSaga(payload) {
  try {
    const response = yield call(postJobService, payload);
    yield [
      put({ type: 'POST_JOB_SUCCESS', response })
    ];
  } catch(error) {
    yield put({ type: 'POST_JOB_ERROR', error });
  }
}

And here is the service.

import { getCookie } from '../../../../utils/cookies';

export const postJobService = (request) => {
  return fetch('http://localhost:3000/api/v1/employer/jobs', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': getCookie('token'),
      },
      body: JSON.stringify(request.payload)
    })
    .then(response => {
      return response.json();
    })
    .then(json => {
      return json;
    })
    .catch(error => {
      return error;
    });
};

Any idea how can I fix this? I am new to testing.


Get this bounty!!!

#StackBounty: #reactjs #react-hooks How to run code on React.useReducer bailout

Bounty: 200

I am trying to write a library that processes dispatched useReducer actions. However, they need to be processed only once I have the new react state.

The idea in the following example is to buffer all the actions as they happen and then after the component rerenders get the new state and send all the buffered actions with the new state into the processor (simple logger function in this case). Problem is, that won’t work if the component bails out of rendering, because the component won’t rerender and so the useEffect callback won’t get called either.

function logger(action, state) {
    // this should log every action immediately once its processed by react
    // state must be up-to-date (after all batched state changes are processed)
    console.log({action, state});
}
const buffer = [];

const Component = () => {
    const [state, dispatch] = useReducer(
        (state, action) => {
            // bail out if there is no change
            if (action.value === state.someState) return state;
            return {someState: action.value};
        },
        {someState: 1}
    );
    const loggedDispatch = (action) => {
        dispatch(action);
        // Can't run the logger here as I don't have the new state yet
        // so I am buffering the actions instead for later
        buffer.push(action);
    };
    useEffect(() => {
        // Now I have the new state, so I can run the logger
        // Problem is that this won't run if the reducer bailed out of render
        while (buffer.length) {
            logger(buffer.shift(), state);
        }
    });
    return (
        <div>
            <div onClick={() => loggedDispatch({value: 1})}>Set to 1</div>
            <div onClick={() => loggedDispatch({value: 2})}>Set to 2</div>
        </div>
    );
};

Any idea how to fix this with react hooks?

With class components it was possible to use

this.setState(state => state, function () {
    console.log('This runs regardless of bailout');
})

But react hooks such as useState or useReducer don’t support the second parameter.

Codesandbox: https://codesandbox.io/s/friendly-pine-lebrb?file=/src/App.js


Get this bounty!!!

#StackBounty: #reactjs #typescript #node-modules #styled-components #decentralized-applications Cannot Change Styled Components Theme P…

Bounty: 50

I’m trying to fork the PancakeSwap exchange interface from GitHub and add my own styling to it. The problem is I haven’t found a way to change the header nav panel as well as 80% of the rest of the react ts components.

I’ve followed multiple tutorials and have been reading up on typescript’s styled-component documentation but I haven’t been able to find any examples or documentation that is similar to Pancakeswap’s ThemeProvider setup.

The core theme provider code that is used is: pancake-uikit – Here is where all my confusion lies and where I haven’t been able to find any documentation for this type of theme setup.

If you visit the pancake-uikit repository I linked for Pancakeswap, you can see all of the core styled-components related code.

To make my question easier to understand I will provide a Diagram of my project setup:
enter image description here

Here is a picture of pancakeswap:
enter image description here

Here is a picture of of what I’ve been able to change:
enter image description here

The github repo for my code is here: https://github.com/CJ-Miller/andromeda-swap

I know this is a very open-ended question but I’m on week 2 of trying to get this to work and any help would be greatly appreciated.


Get this bounty!!!

#StackBounty: #reactjs #ckeditor Ckeditor5 react plugin creating different toolbars – getting 'subscript', 'superscript&#39…

Bounty: 50

I’ve got the basic CKeditor5 installed — but I am unable to add some toolbars to the plugin.

https://www.npmjs.com/package/ckeditor5

import { CKEditor } from '@ckeditor/ckeditor5-react';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';

‘subscript’, ‘superscript’ are not showing up? I think its part of the basic styles feature -but do I need to include it here? replace the type of editor it is? Why isn’t this working?

  <CKEditor
    editor={ClassicEditor}
    config={{
      toolbar: {
          items: [
              'heading', '|',
              'fontfamily', 'fontsize', '|',
              'alignment', '|',
              'fontColor', 'fontBackgroundColor', '|',
              'bold', 'italic', 'strikethrough', 'underline', 'subscript', 'superscript', '|',
              'link', '|',
              'outdent', 'indent', '|',
              'bulletedList', 'numberedList', 'todoList', '|',
              'code', 'codeBlock', '|',
              'insertTable', '|',
              'uploadImage', 'blockQuote', '|',
              'undo', 'redo'
          ],
          shouldNotGroupWhenFull: true
      }
    }}          
    data={input.value}
    onReady={ editor => {
      // You can store the "editor" and use when it is needed.
      //console.log( 'Editor is ready to use!', editor );
    }}
    onChange={ ( event, editor ) => {
        const value = editor.getData();
        //console.log( { event, editor, value } );
        input.onChange(value);
        onHandle(input.name, value);
    }}
    onBlur={ ( event, editor ) => {
      //console.log( 'Blur.', editor );
    }}
    onFocus={ ( event, editor ) => {
      //console.log( 'Focus.', editor );
    }}
  />


Get this bounty!!!

#StackBounty: #javascript #reactjs #react-hooks #react-grid-layout How to handle condition rendering in react

Bounty: 100

I am using react-grid-layout This to enable drag and drop and resizing in my website.
SO drag and drop I am able to achieve and storing my layout to local storage is also done.

I am using Local storage to save my layout for better user experience using This example

the thing is what I am trying to do is conditionally give height and width to boxes, like if empName==="steve" than width should be 5 or else it should be 3

So what I did is

const generateLayout = () => {
  const p = data1 || []; //props;
  return p[0].comp_data.map(function (item, i) {
    console.log(item);
    if (item.empName === "steve") {
      return {
        x: (i * 2) % 12,
        y: Math.floor(i / 6),
        w: 2,
        h: 4,
        i: i.toString()
      };
    } else {
      return {
        x: (i * 2) % 12,
        y: Math.floor(i / 6),
        w: 4,
        h: 2,
        i: i.toString()
      };
    }
  });
};

The above approach does not work as required.

Here is the full working code

Edit update

I changed my data, as it was wrong I was looping through p[0]

Now what I did is I created one data for tabs That will show menu ie

    let tabData = [
    {
        tab: 'info',
        id: 1,
    },
    {
        tab: 'info1',
        id: 2,
    },
];

and the other one I have is compData that will have emp status

LIke below

    let data1 = [
    {
        comp_data: [
            {
                empId: 1,
                empName: 'el1',
            },
            {
                empId: 2,
                empName: 'el2',
            },
        ],
    },
    {
        comp_data: [
            {
                empId: 11,
                empName: 'el11',
            },
            {
                empId: 12,
                empName: 'el22',
            },
        ],
    },
];

Important — actually in my real scenario I am getting all the tabs at one go than I click on one tab get id of that and get compData for that id from backend but here I cannot do it so I put in data1 two objects one for first company and other for other company.

I think this the way for write explanation here

updated code sandbox please check


Get this bounty!!!