Post-interview FE Coding Insights in 2025

Nuro 45-min FE Interview - late-June

Problem description:

1
2
3
Self dismissing modal
1. When button is clicked, modal should cover the page
2. After 5 seconds, the modal closes on it's own

Revised implementation w/o error risk when using JSX element VS functional call:

App.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import './App.css';
import 'h8k-components';
import React, { useState, useEffect } from 'react';
const title = "React App";
const App = () => {
const [count, setCount] = useState(0);
const [modalVisible, setModalVisible] = useState(false);

useEffect(() => {
if (modalVisible) {
const interval = setInterval(() => {
if (modalVisible && count > 0) {
setCount(count => count - 1);
}
}, 1000);

return () => {
clearInterval(interval);
}
}
}, [modalVisible]);
// step 1: add a basic modal as an overlay
// step 3: enable auto-closing in the modal
const Modal = () => (
<div style={{ display: modalVisible ? 'flex' : 'none', flexDirection: 'column', padding: '18px' }}>
<h2>This is a modal</h2>
<p>Countdown: {count} second(s) left ...</p>
</div>);
return (
<div className="App">
<Modal />
{/* {Modal()} */}
<h8k-navbar header={title}></h8k-navbar>
<div className="fill-height layout-column justify-content-center align-items-center">
{/* step 2: replace the button to open the model */}
<button onClick={() => {
setModalVisible(true);
setCount(5);
setTimeout(() => setModalVisible(false), 5000);
}} disabled={modalVisible}>Open Modal</button>
</div>
</div>
);
}
export default App;

Original defective implementation during the interview:

./src/App.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import './App.css';
import 'h8k-components';
import React, { useState, useEffect } from 'react';
const title = "React App";
// Self dismissing modal
// 1. When button is clicked, modal should cover the page
// 2. After 5 seconds, the modal closes on it's own
const App = () => {
const [count, setCount] = useState(0);
const [modalVisible, setModalVisible] = useState(false);
const [countDown, setCountDown] = useState(false);
// if (countDown) {
// setCountDown(false);
// setInterval(() => {
// if (modalVisible && count > 0) {
// console.log('time left:', count);
// setCount(count => count - 1);
// }
// }, 1000);
// }
useEffect(() => {
console.log('modal visible:', modalVisible);
if (modalVisible && !countDown) {
setInterval(() => {
if (modalVisible && count > 0) {
console.log('time left:', count);
// setCount(count => count - 1);
}
}, 1000);
}
return () => {
clearTimeout();
}
}, [modalVisible]);
// step 1: add a basic modal as an overlay
const Modal = () => {
// useEffect(() => {console.log('useEffect time left:', count);}, [count]);

// step 3: enable auto-closing in the modal
return (<div style={{ display: modalVisible ? 'flex' : 'none', flexDirection: 'column', padding: '18px' }}>
<h2>This is a modal</h2>
<p>Countdown: {count} second(s) left ...</p>
</div>)
};
return (
<div className="App">
<Modal />
{/* {Modal()} */}
<h8k-navbar header={title}></h8k-navbar>
<div className="fill-height layout-column justify-content-center align-items-center">
{/* <p data-testid="output">You clicked {count} times ...</p> */}
{/* <button data-testid="add-button" onClick={() => setCount(count + 1)}>Click Me</button> */}
{/* step 2: replace the button to open the model */}
<button onClick={() => {
setModalVisible(true);
setCount(5);
setTimeout(() => setModalVisible(false), 5000);
setCountDown(true);
}} disabled={modalVisible}>Open Modal</button>
</div>
</div>
);
}
export default App;
./src/App.css
1
@import '../node_modules/h8k-design/dist/index.css';
./src/index.js
1
2
3
4
5
6
7
8
9
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {applyPolyfills, defineCustomElements} from 'h8k-components/loader';

ReactDOM.render(<App />, document.getElementById('root'));
applyPolyfills().then(() => {
defineCustomElements(window);
})
package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
"name": "react-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"h8k-components": "^1.0.0",
"h8k-design": "^1.0.16",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1",
"@testing-library/jest-dom": "5.16.1",
"@testing-library/react": "12.1.2"
},
"scripts": {
"prestart": "npm install",
"start": "cross-env HOST=0.0.0.0 PORT=8000 ./node_modules/.bin/react-scripts start"
},
"devDependencies": {
"cross-env": "^7.0.2"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

Yahoo Final Rounds - FE Section - mid-March

External references after revision:

  • useRef is a React Hook that lets you reference a value that’s not needed for rendering.

  • Window.fetch() – no need to import axios when in a pitch.

    Basic usage:

    1
    2
    3
    4
    5
    6
    const response = await fetch(url);
    if (!response.ok) {
    throw new Error(`Response status: ${response.status}`);
    }

    const json = await response.json();

Revised implementation of App component:

App.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

function App() {
const [comments, setComments] = useState([]);
const [inputValue, setInputValue] = useState({
id: '',
name: '',
email: '',
body: '',
});

const getComments = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1/comments');
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}

const json = await response.json();
console.log('resp:', json);
setComments(json);
} catch (error) {
console.error(error.message);
}
};
const submitComment = (event) => {
event.preventDefault();

// update comment list
const newComment = {
...inputValue
};
console.log('inputs:', newComment);
setComments((prevComments) => [newComment, ...prevComments]);
setInputValue({ id: '', name: '', email: '', body: '' });
// POST new comment ...
};
useEffect(() => {
getComments();
}, []);

return (
<div className="app">
<h1>Comments</h1>
<form>
<div>
<span>ID:</span>
<input id="id-input" type="text" value={inputValue.id} onChange={(e) => setInputValue((prevInput) => {
return { ...prevInput, id: e.target.value }
})}/>
</div>
<div>
<span>Name:</span>
<input id="name-input" type="text" value={inputValue.name} onChange={(e) => setInputValue((prevInput) => {
return { ...prevInput, name: e.target.value }
})}/>
</div>
<div>
<span>Email:</span>
<input id="email-input" type="text" value={inputValue.email} onChange={(e) => setInputValue((prevInput) => {
return { ...prevInput, email: e.target.value }
})}/>
</div>
<div>
<span>Content:</span>
<input id="comment-input" type="text" value={inputValue.body} onChange={(e) => {
// console.log('Input onchange:', e.target.value, e.currentTarget.value);
// setInputValue(e.target.value);
setInputValue((prevInput) => {
return { ...prevInput, body: e.target.value }
})
}} />
</div>
<button type="submit" onClick={submitComment}>Submit Comment</button>
</form>
<ul>
{
comments.map((comment) => {
const { id, name, email, body } = comment;
return (
<li key={`comment-key-${id}`}>
<div>
<h4>{name} {email}</h4>
<p>{body}</p>
</div>
</li>
);
})
}
</ul>
</div>
)
}
export default App;

Wisdom AI 60-min Screening in FE - early-Feb

Problem: Implement a FE page of basic card game using stackblitz.com online IDE (JS only, no TS support).

Constants
1
2
const numbers = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'];
const suits = ['♠', '♣', '♥', '♦'];

Revised coding (online IDE / Live Demo):

style.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
h1,
p {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
.card-list {
display: flex;
column-gap: 4px;
}
.card {
border: 2px solid green;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
/* text-align: center; */
min-width: 50px;
min-height: 30px;
}
App.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import React, { useState } from 'react';
import './style.css';
const numbers = [
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'J',
'Q',
'K',
'A',
];
const suits = ['♠', '♣', '♥', '♦'];
const generate_card = () => {
const random_num = Math.floor(Math.random() * numbers.length);
const random_suit = Math.floor(Math.random() * suits.length);
return numbers[random_num] + suits[random_suit];
};
const draw_cards = (card_num) => {
const cards = new Set();
while (cards.size < card_num) {
const new_card = generate_card();
if (cards.has(new_card)) {
continue;
}
cards.add(new_card);
}
return Array.from(cards);
};
export default function App() {
const [cardNum, setCardNum] = useState(5);
const [cardList, setCardList] = useState([]);
const deal_a_hand = () => {
setCardList(() => {
const cards = draw_cards(cardNum);
return cards.map((card) => <span className="card">{card}</span>);
});
setCardNum(4);
};
return (
<div>
{/* <h1>Hello StackBlitz!</h1>
<p>Start editing to see some magic happen :)</p> */}
<button onClick={deal_a_hand}>Deal a Hand</button>
<h2>Cards</h2>
<div className="card-column">
<p className="card-list">{cardList}</p>
</div>
</div>
);
}

Post-interview FE Coding Insights in 2025

https://devblog.citruxonve.net/posts/d0983c6a/

Author

CitruXonve

Posted on

03/10/2025

Updated on

07/13/2025

Licensed under

Comments