Thursday, 1 June 2023

How is props.children added inside opening and closing tags in React JS with children="xyz" attribute?

This is how I understand props.children in React:

class ThemedButton extends React.Component {
  render() {
    console.log(this.props);
    return ( <
      button > {
        this.props.children
      }
      " 12345" <
      /button>
    );
  }
}

function Toolbar(props) {
  return ( <
    ThemedButton onClick = {
      props.changeTheme
    } >
    Change Theme <
    /ThemedButton>
  );
}



ReactDOM.render( < Toolbar / > , document.getElementById('root'));
//this will generate <button>Change Theme 12345</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


<div id="root"></div>

So basically any child node(s) of ThemedButton will be put in place of props.children. This makes sense, but what doesn't make sense is if I omit props.children and instead just pass {...props} as attribute or use children attribute as property on the button tag, it still inserts the child node(s). Following is the example:

class ThemedButton extends React.Component {
  render() {
    console.log(this.props);
    return ( 
    <button {...this.props}  ></button>  //child nodes are added automatically     
    );
  }
}

class ThemedButton2 extends React.Component {
  render() {
    console.log(this.props);
    return ( 
    <button children="XYZ"  ></button>
    );
  }
}


function Toolbar(props) {
  return ( 
  <React.Fragment>
    <
    ThemedButton onClick = {
      props.changeTheme
    } >
    Change Theme <
    /ThemedButton>
    <ThemedButton2> Change theme2 </ThemedButton2>
  </React.Fragment>
  );
}



ReactDOM.render( < Toolbar / > , document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>

<div id="root"></div>

As you can see {...props} on button seemingly brings actual child nodes of ThemedButton> as children property. In ThemedButton2 I manually provided children="xyz", which automatically inserts xyz as child nodes of button.

Why is this happening? Where does react explain this in it's official documentation?



from How is props.children added inside opening and closing tags in React JS with children="xyz" attribute?

Why doesn't os.path.join() work in this case?

The below code will not join, when debugged the command does not store the whole path but just the last entry.

os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/')

When I test this it only stores the /new_sandbox/ part of the code.



from Why doesn't os.path.join() work in this case?

Can we write typescript inside a svelte component?

Is it possible to write Typescript inside the script tag in a svelte component?

I came across https://github.com/pyoner/svelte-typescript/tree/master/packages/preprocess Which if I understand correctly is a typescript preprocessor for svelte which would allow to write typescript in svelte components. However I am not able to get it working

This is how my rollup config looks like

import svelte from "rollup-plugin-svelte";
import resolve from "rollup-plugin-node-resolve";
import replace from "rollup-plugin-replace";
import commonjs from "rollup-plugin-commonjs";
import serve from "rollup-plugin-serve";
import livereload from "rollup-plugin-livereload";
import copy from "rollup-plugin-copy";
import typescript from "rollup-plugin-typescript2";
import { terser } from "rollup-plugin-terser";

import {
  preprocess,
  createEnv,
  readConfigFile
} from "@pyoner/svelte-ts-preprocess";

const tsEnv = createEnv();
const compilerOptions = readConfigFile(tsEnv);
const opts = {
  env: tsEnv,
  compilerOptions: {
    ...compilerOptions,
    allowNonTsExtensions: true
  }
};

const env = process.env.NODE_ENV;

const production = env ? env === "production" : false;
const distFolder = "dist";

export default {
  input: "src/index.ts",
  output: {
    sourcemap: !production,
    format: "iife",
    name: "app",
    file: `${distFolder}/bundle.js`
  },
  plugins: [
    replace({
      "process.browser": true,
      "process.env.NODE_ENV": JSON.stringify(env)
    }),
    svelte({
      // enable run-time checks when not in production
      dev: !production,
      // we'll extract any component CSS out into
      // a separate file — better for performance
      css: css => {
        css.write(`${distFolder}/bundle.css`);
      },
      preprocess: preprocess(opts)
    }),

    // If you have external dependencies installed from
    // npm, you'll most likely need these plugins. In
    // some cases you'll need additional configuration —
    // consult the documentation for details:
    // https://github.com/rollup/rollup-plugin-commonjs
    resolve({
      browser: true,
      dedupe: importee =>
        importee === "svelte" || importee.startsWith("svelte/")
    }),
    commonjs(),
    typescript({
      tsconfig: "tsconfig.json",
      objectHashIgnoreUnknownHack: true,
      clean: production
    }),

    // Start dev server if not in production mode
    !production &&
      serve({
        open: true,
        contentBase: distFolder,
        historyApiFallback: true,
        host: "localhost",
        port: 7000
      }),

    // Watch the `dist` directory and refresh the
    // browser on changes when not in production
    !production && livereload(distFolder),

    // If we're building for production (npm run build
    // instead of npm run dev), minify
    production && terser(),
    copy({
      targets: [{ src: "public/**/*", dest: `${distFolder}` }]
    })
  ],
  watch: {
    clearScreen: false
  }
};

I am not sure If I have configured this incorrectly or if it is not possible at all to write typescript in svelte?



from Can we write typescript inside a svelte component?